Webhooks de MirtaAI
Cada vez que pasa algo que elegiste (un lead nuevo, un chat cerrado, un pago acreditado), MirtaAI le manda a tu sistema un POST con un JSON firmado. Así tu CRM, tu planilla o tu herramienta de automatización se enteran al momento.
Los webhooks se configuran en la app, en Configuración → API y webhooks (plan Pro), con quien administra las integraciones. Versión del formato: 2026-10-01.
Formato
El cuerpo es siempre un objeto con el mismo encabezado y, en data, lo propio de cada evento. Las fechas van en ISO 8601 y en UTC.
- id
- El id del evento. Es el mismo en todos los intentos: usalo para descartar repetidos.
- type
- El tipo de evento, por ejemplo
conversation.closed. - version
- La versión del formato (
2026-10-01). Si cambia de forma incompatible, cambia la versión. Pueden aparecer tipos de evento y valores nuevos sin cambiarversion: ignorá lo que no conozcas. - occurred_at
- Cuándo pasó el hecho (no cuándo se mandó).
- company
- La empresa:
idyname. - data
- Lo del evento: casi siempre
conversation(con el link al chat) ycontact, más su parte propia.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f04",
"type": "conversation.closed",
"version": "2026-10-01",
"occurred_at": "2026-09-30T18:04:11.201Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"by_automation": false,
"by_mirta": false,
"closed_by": {
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "closed",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
}
}
}Encabezados
| Encabezado | Qué es |
|---|---|
| Content-Typeapplication/json | El cuerpo es JSON en UTF-8. |
| User-AgentMirtaAI-Webhooks/1.0 (+https://mirta.app/desarrolladores/webhooks) | Identifica los envíos de MirtaAI. |
| Mirta-Event-Id0192a4d0-… | El id del evento: el mismo en todos los intentos y reenvíos. Usalo para descartar repetidos. |
| Mirta-Event-Typeconversation.closed | El tipo de evento (igual a type del cuerpo). |
| Mirta-Delivery-Id0192a4e2-… | La entrega a tu webhook. Sirve para buscarla en el registro de Configuración. |
| Mirta-Attempt1 | Número de intento: 1 la primera vez, 2 en el primer reintento… |
| Mirta-Signaturet=1790856000,v1=5ca3… | La firma: la hora en segundos Unix y uno o dos HMAC-SHA256 (dos mientras dura una rotación del secreto). |
Verificar la firma
Cada webhook tiene su secreto (whsec_…), que se ve una sola vez al crearlo o al rotarlo. Con él, MirtaAI firma cada envío:
- Tomá
ty cadav1deMirta-Signature(t=1790856000,v1=…). - Calculá el HMAC-SHA256 en hexadecimal de
<t>.<cuerpo>con el secreto, sobre el cuerpo tal cual llegó (sin parsearlo ni volver a armarlo). - Comparalo con cada
v1en tiempo constante: si alguno coincide, la firma es válida. - Rechazá un
tde más de 5 minutos de diferencia con tu reloj: protege contra repeticiones.
Al rotar el secreto, durante 24 horas el encabezado trae dos v1: uno con el secreto nuevo y otro con el anterior. Cargá el nuevo en tu sistema dentro de ese plazo y no se corta nada.
Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
// encabezado: el valor de Mirta-Signature. cuerpo: el cuerpo tal cual llegó, como texto (sin parsear ni reformatear).
// secretos: el vigente y, mientras dura una rotación, también el anterior.
export function firmaValida(encabezado, cuerpo, secretos, toleranciaSeg = 300, ahora = Date.now() / 1000) {
const partes = encabezado.split(",").map((p) => p.trim().split("="));
const t = Number(partes.find(([k]) => k === "t")?.[1]);
const firmas = partes.filter(([k]) => k === "v1").map(([, v]) => v ?? "");
if (!Number.isInteger(t) || firmas.length === 0) return false;
if (Math.abs(ahora - t) > toleranciaSeg) return false; // más de 5 minutos: puede ser una repetición
return secretos.some((secreto) => {
const esperada = Buffer.from(createHmac("sha256", secreto).update(`${t}.${cuerpo}`).digest("hex"));
return firmas.some((f) => f.length === esperada.length && timingSafeEqual(Buffer.from(f), esperada));
});
}import express from "express";
import { firmaValida } from "./firma.js";
const app = express();
const vistos = new Set(); // en producción, una tabla con índice único por id
// express.text: el cuerpo llega como texto, igual que se firmó.
app.post("/mirta", express.text({ type: "application/json" }), (req, res) => {
if (!firmaValida(req.get("Mirta-Signature") ?? "", req.body, [process.env.MIRTA_WEBHOOK_SECRET])) {
return res.sendStatus(401);
}
const evento = JSON.parse(req.body);
if (!vistos.has(evento.id)) {
vistos.add(evento.id);
// Guardalo o ponelo en una cola y procesalo después: respondé en menos de 10 s.
}
res.sendStatus(200);
});Python
from __future__ import annotations
import hashlib
import hmac
import time
def firma_valida(encabezado: str, cuerpo: bytes, secretos: list[str], tolerancia_seg: int = 300, ahora: float | None = None) -> bool:
"""encabezado: Mirta-Signature. cuerpo: los bytes tal cual llegaron. secretos: el vigente y, en una rotación, el anterior."""
partes = [p.strip().partition("=") for p in encabezado.split(",")]
t = next((v for k, _, v in partes if k == "t"), "")
firmas = [v for k, _, v in partes if k == "v1"]
if not t.isdigit() or not firmas:
return False
if abs((time.time() if ahora is None else ahora) - int(t)) > tolerancia_seg:
return False # más de 5 minutos: puede ser una repetición
for secreto in secretos:
esperada = hmac.new(secreto.encode(), t.encode() + b"." + cuerpo, hashlib.sha256).hexdigest()
if any(hmac.compare_digest(f, esperada) for f in firmas):
return True
return Falsefrom flask import Flask, abort, request
import json, os
app = Flask(__name__)
@app.post("/mirta")
def mirta():
cuerpo = request.get_data() # los bytes, sin parsear
if not firma_valida(request.headers.get("Mirta-Signature", ""), cuerpo, [os.environ["MIRTA_WEBHOOK_SECRET"]]):
abort(401)
evento = json.loads(cuerpo)
# Descartá los repetidos por evento["id"]; guardalo y respondé en menos de 10 s.
return "", 200Para probar tu código
Con este secreto inventado, el cuerpo de la prueba de abajo y esta hora, la firma tiene que dar exactamente esto:
- Secreto
- whsec_IyAbg60FurHTFUm2Gbqlhscf6o_iidfnMRE5hRV-p40
- t
- 1790856000
- Encabezado
- t=1790856000,v1=5ca313bfab1197325ac274bd88e0b662dcccc59a4d94e5c9de30aa59ffff9e76
{"id":"0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f19","type":"webhook.test","version":"2026-10-01","occurred_at":"2026-10-01T12:00:00.000Z","company":{"id":"c0000000-0000-4000-8000-000000000001","name":"Autos del Sur"},"data":{"message":"Envío de prueba de MirtaAI: si lo recibiste, el webhook está bien configurado.","test":true}}Eventos
Elegís a qué eventos se suscribe cada webhook. Los de «Otros» llegan sin suscribirse: los manda la acción «Enviar a un webhook» de una automatización o el botón «Enviar prueba».
Chats
Mensaje nuevo
message.receivedEl cliente escribió en un chat (cualquier canal). Con palabras clave, es el disparador «Palabra clave».
El texto (o la transcripción de un audio) solo sale si el webhook tiene «Incluir el texto de los mensajes». La media nunca: solo el tipo.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f01",
"type": "message.received",
"version": "2026-10-01",
"occurred_at": "2026-09-30T14:21:07.512Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"message": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f02",
"opt_out": false,
"text": "Hola, ¿sigue disponible el Corolla 2020?",
"type": "text"
}
}
}Lead nuevo
conversation.createdSe abrió un chat nuevo: un cliente escribió por primera vez o entró un lead de un portal.
origin es organic, ad, link o portal.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f03",
"type": "conversation.created",
"version": "2026-10-01",
"occurred_at": "2026-09-30T14:21:07.498Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"origin": "ad"
}
}Chat cerrado
conversation.closedUna persona, una automatización o Mirta cerró el chat.
by_mirta es true cuando lo cerró Mirta porque quedó resuelto (atención completa); entonces closed_by es null.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f04",
"type": "conversation.closed",
"version": "2026-10-01",
"occurred_at": "2026-09-30T18:04:11.201Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"by_automation": false,
"by_mirta": false,
"closed_by": {
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "closed",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
}
}
}Contactos
Lead de portal
lead.portal_receivedEntró una consulta de un portal (Zonaprop, Argenprop, Mercado Libre…), nueva o sumada a un chat.
La consulta escrita (portal_lead.message) solo sale con «Incluir el texto de los mensajes».
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f05",
"type": "lead.portal_received",
"version": "2026-10-01",
"occurred_at": "2026-09-30T11:02:45.120Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"portal_lead": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f06",
"listing": {
"id": "MLA1499321850",
"title": "Toyota Corolla 2.0 Xei 2020",
"url": "https://auto.mercadolibre.com.ar/MLA-1499321850"
},
"message": "¿Aceptan permuta por un Etios 2017?",
"source": "mercadolibre"
}
}
}Pidió la baja
contact.opted_outEl cliente pidió no recibir más mensajes (por mensaje, cargado a mano o avisado por Meta).
source es message (lo pidió por mensaje), manual, form o meta (Meta avisó que dejó de aceptar promociones de tu empresa en WhatsApp; solo whatsapp_marketing).
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f14",
"type": "contact.opted_out",
"version": "2026-10-01",
"occurred_at": "2026-09-30T19:30:12.000Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"opt_out": {
"channels": [
"whatsapp_marketing"
],
"source": "meta"
}
}
}Datos suprimidos
contact.erasedSe suprimieron los datos de un contacto a pedido del titular: borrá tu copia.
Solo lleva el id del contacto: con él, borrá lo que guardaste de esa persona.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f15",
"type": "contact.erased",
"version": "2026-10-01",
"occurred_at": "2026-10-01T10:00:00.000Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21"
}
}
}Contactos unidos
contact.mergedUna persona del equipo unió dos contactos del mismo cliente: el absorbido pasa a ser parte del que quedó.
El contacto es el que quedó; merge.absorbed_id es el que dejó de existir: uní sus dos registros.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f40",
"type": "contact.merged",
"version": "2026-10-01",
"occurred_at": "2026-10-01T11:15:40.000Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": null,
"merge": {
"absorbed_id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a29",
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f41",
"survivor_id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21"
}
}
}Contactos separados
contact.splitUna persona del equipo separó una unión de contactos: el absorbido vuelve a ser un contacto aparte.
Durante 30 días una unión se puede separar: merge.absorbed_id vuelve a existir, con el mismo id.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f42",
"type": "contact.split",
"version": "2026-10-01",
"occurred_at": "2026-10-03T09:02:11.000Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": null,
"merge": {
"absorbed_id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a29",
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f41",
"survivor_id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21"
}
}
}Embudo
Etapa cambiada
opportunity.stage_changedUna oportunidad pasó a otra etapa del embudo (también al marcarla ganada o perdida).
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f09",
"type": "opportunity.stage_changed",
"version": "2026-10-01",
"occurred_at": "2026-09-30T15:12:30.440Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"opportunity": {
"from_stage": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b72",
"name": "Contactado"
},
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f10",
"pipeline": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b71",
"name": "Ventas"
},
"status": "open",
"title": "Toyota Corolla 2020",
"to_stage": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b73",
"name": "Prueba de manejo"
}
}
}
}Pagos
Pago acreditado
payment.approvedSe acreditó un link de pago (seña, reserva o total). El webhook lleva el monto.
Lleva el monto: para suscribirlo, quien configura el webhook tiene que poder ver la facturación.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f07",
"type": "payment.approved",
"version": "2026-10-01",
"occurred_at": "2026-09-30T16:40:02.003Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"payment": {
"amount": 500000,
"concept": "Seña Toyota Corolla 2020",
"currency": "ARS",
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f08",
"kind": "sena",
"paid_at": "2026-09-30T16:39:58.000Z"
}
}
}Transferencia confirmada
payment.transfer_confirmedUna persona del equipo confirmó una transferencia después de verla en el banco. El webhook lleva el monto.
Lleva el monto y la moneda que confirmó la persona (ARS o USD, nunca convertidos). Una lectura por IA nunca la confirma sola. Si alguien después anula la confirmación, no llega otro evento. Como el pago acreditado, pide poder ver la facturación.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f20",
"type": "payment.transfer_confirmed",
"version": "2026-10-01",
"occurred_at": "2026-09-30T17:05:11.250Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"transfer": {
"amount": 150000,
"confirmed_at": "2026-09-30T17:05:11.000Z",
"currency": "ARS",
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f21",
"paid_on": "2026-09-29",
"status": "confirmed"
}
}
}Encuestas
Encuesta respondida
csat.answeredEl cliente respondió la encuesta de satisfacción con una nota del 1 al 5.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f11",
"type": "csat.answered",
"version": "2026-10-01",
"occurred_at": "2026-09-30T18:09:55.731Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "closed",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"survey": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f12",
"score": 5
}
}
}Campañas
Respondió una campaña
campaign.repliedEl cliente respondió una campaña dentro de las 72 horas de recibirla. Podés elegir de qué campañas.
Lleva la campaña, la variante (A, B o null sin prueba A/B) y el id del mensaje. El texto de la respuesta llega en «Mensaje nuevo».
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f20",
"type": "campaign.replied",
"version": "2026-10-01",
"occurred_at": "2026-10-02T13:12:40.118Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"campaign": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f21",
"name": "Usados de octubre",
"variant": "A"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"message": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f22"
}
}
}Campaña terminada
campaign.finishedUna campaña terminó de enviarse: lleva cuántos la recibieron, cuántos se saltearon, respondieron o pidieron la baja.
No es de un chat: conversation y contact van en null. Los entregados y leídos siguen cambiando después: miralos en MirtaAI.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f23",
"type": "campaign.finished",
"version": "2026-10-01",
"occurred_at": "2026-10-03T17:40:02.500Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"campaign": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f21",
"name": "Usados de octubre"
},
"contact": null,
"conversation": null,
"counts": {
"failed": 10,
"opted_out": 15,
"recipients": 950,
"replied": 41,
"sent": 905,
"skipped": 35
}
}
}Aprobaciones de Mirta
Pedido de aprobación
approval.requestedMirta o un vendedor pidió aprobación para mandar un link de pago, agendar un turno o dar un descuento.
action es payment_link, schedule o discount, y requested_by, mirta o user. Los pedidos no llevan montos ni textos.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f20",
"type": "approval.requested",
"version": "2026-10-01",
"occurred_at": "2026-10-01T15:10:42.318Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"approval": {
"action": "payment_link",
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f21",
"reason": "policy",
"requested_by": "mirta"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
}
}
}Pedido aprobado o rechazado
approval.decidedUna persona del equipo aprobó (con o sin cambios) o rechazó un pedido de aprobación.
decision es approved o rejected; edited dice si se aprobó con cambios.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f22",
"type": "approval.decided",
"version": "2026-10-01",
"occurred_at": "2026-10-01T15:14:03.907Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"approval": {
"action": "payment_link",
"decision": "approved",
"edited": false,
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f21"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"decided_by": {
"id": "a0000000-0000-4000-8000-000000000002",
"name": "Gabriela López"
}
}
}Pedido vencido
approval.expiredUn pedido de aprobación venció sin que nadie lo resolviera.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f23",
"type": "approval.expired",
"version": "2026-10-01",
"occurred_at": "2026-10-01T17:10:42.318Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"approval": {
"action": "schedule",
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f24"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "open",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
}
}
}Otros
Enviado por un flujo
flow.webhookLo manda la acción «Enviar a un webhook» de un flujo, con el evento que lo disparó.
Lleva su propio id (uno por ejecución y paso), así no se confunde con el evento que lo disparó si además estás suscripto a ese evento.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f16",
"type": "flow.webhook",
"version": "2026-10-01",
"occurred_at": "2026-09-30T18:04:12.950Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"by_automation": false,
"by_mirta": false,
"closed_by": {
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"contact": {
"email": "juan.perez@gmail.com",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a21",
"name": "Juan Pérez",
"phone": "+5491162345718"
},
"conversation": {
"account": {
"id": "0192a4b0-1c3d-7e4f-8a5b-2d3e4f5a6b70",
"name": "Usados"
},
"assignee": {
"email": "carla.rodriguez@autosdelsur.com.ar",
"id": "a0000000-0000-4000-8000-000000000003",
"name": "Carla Rodríguez"
},
"channel": "whatsapp",
"id": "0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20",
"status": "closed",
"url": "https://mirta.app/bandeja/0192a4c1-7d2e-7b10-9a3f-6c2d8e4f1a20"
},
"flow": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f17",
"name": "Avisar al CRM al cerrar"
},
"run_id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f18",
"step_key": "s1",
"trigger": {
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f04",
"occurred_at": "2026-09-30T18:04:11.201Z",
"type": "conversation.closed"
}
}
}Prueba
webhook.testEl envío de prueba de «Enviar prueba» en Configuración → API y webhooks.
{
"id": "0192a4d0-0b1c-7d2e-8f3a-4b5c6d7e8f19",
"type": "webhook.test",
"version": "2026-10-01",
"occurred_at": "2026-10-01T12:00:00.000Z",
"company": {
"id": "c0000000-0000-4000-8000-000000000001",
"name": "Autos del Sur"
},
"data": {
"message": "Envío de prueba de MirtaAI: si lo recibiste, el webhook está bien configurado.",
"test": true
}
}Respuestas y reintentos
Respondé con un código 2xx en menos de 10 segundos: es la única forma de que el envío cuente como entregado. Cualquier otra cosa es una falla: un timeout, un error de red o de certificado, un 3xx (no seguimos redirecciones), un 4xx o un 5xx. Guardamos el código y hasta 1 KB de tu respuesta para mostrarlos en el registro de entregas.
Si falla, reintentamos con el mismo cuerpo y el mismo id de evento, después de esperar (con ±20 % al azar):
- 1 minuto después del primer intento
- 5 minutos después del intento 2
- 30 minutos después del intento 3
- 2 horas después del intento 4
- 6 horas después del intento 5
- 12 horas después del intento 6
- 24 horas después del intento 7
Son 8 intentos en unas 45 horas; si ninguno funciona, la entrega queda «Falló» y se puede reenviar a mano desde Configuración. Con un 429, respetamos tu Retry-After (en segundos o como fecha HTTP), hasta una hora.
Desactivación
- Si respondés
410 Gone, desactivamos el webhook enseguida: es la forma de decir «esta dirección ya no existe». - Si las entregas fallan 24 horas seguidas, avisamos a quienes administran las integraciones de la empresa.
- Si fallan durante 3 días sin ningún envío exitoso, lo desactivamos, cancelamos lo que estaba en cola y avisamos.
- Al reactivarlo desde Configuración se puede reenviar lo que falló en los últimos 7 días, con los mismos ids.
Repetidos y orden
La entrega es al menos una vez: si tu sistema respondió pero la respuesta no nos llegó (o tardó más de 10 s), el mismo evento vuelve a llegar. Guardá el id (o Mirta-Event-Id) de lo que procesaste y descartá los repetidos.
El orden de llegada no está garantizado: un reintento puede llegar después de un evento más nuevo. Para ordenar, usá occurred_at. Lo más seguro es responder 200 apenas guardás el evento y procesarlo después.
Qué datos salen
- Siempre: ids de MirtaAI, tipo, fechas, canal, cuenta, estado, etapa, origen, la persona asignada y el nombre, teléfono y email del contacto.
- El texto de los mensajes (y de la consulta de un portal) solo si el webhook tiene «Incluir el texto de los mensajes», que solo puede prender quien ve todos los chats.
- La media (fotos, audios, documentos) nunca: solo su tipo.
- Los montos, solo en «Pago acreditado».
- Cuando se suprimen los datos de un contacto llega
contact.erasedcon su id: borrá tu copia.
La empresa elige adónde van sus webhooks y es responsable de ese destino, que no es un subprocesador de MirtaAI (ver los términos y la página de confianza).
Direcciones permitidas
La dirección tiene que ser https://, en el puerto 443 u 8443, sin usuario ni contraseña, y apuntar a internet: no se aceptan localhost, nombres internos (.local, .internal) ni direcciones de redes privadas, tampoco si el dominio resuelve a una. Lo verificamos al guardar y en cada envío.