API Chat en Vivo — Integración con su servidor (1.0)

Download OpenAPI specification:Download

INTRODUCCION

Integración del Chat en Vivo con su propio servidor: cada vez que se produce un mensaje en una conversación le enviamos una petición POST (JSON) a la URL que usted configure, y lo que su servidor responda se aplica en la conversación: contestar al visitante, ofrecerle botones o cerrar el chat.



Así su propia lógica de negocio puede responder en tiempo real: consultar el estado de un pedido en su ERP y contestarlo, identificar al visitante contra su CRM, lanzar una encuesta con botones y guardar la respuesta, o registrar toda la conversación en su sistema de tickets.



No hace falta que responda nada. Si su servidor no contesta, contesta tarde o devuelve algo que no es JSON, la conversación sigue con normalidad y la atiende su agente como siempre. La integración nunca bloquea el chat.

ACTIVACIÓN

En su panel: Chat → Sitios web, edite el sitio y rellene la sección «Reports a tu servidor»:
- URL (https): debe ser https y un host público. Por seguridad se rechazan las IPs privadas o reservadas (127.0.0.1, 10.x, 192.168.x, ::1…) y no se siguen redirecciones.
- Autenticación: el valor que escriba aquí se envía tal cual en la cabecera Authorization de cada petición (por ejemplo Bearer mi_token_secreto). Compruébelo en su servidor y rechace lo que no cuadre.



La configuración es de la cuenta, no del sitio: se toma la del primer sitio activo que tenga URL, y se aplica a todas las conversaciones de la cuenta, vengan del widget web o de WhatsApp, SMS o email.

CÓMO ES LA PETICIÓN

Siempre POST con Content-Type: application/json, el cuerpo en JSON y un tiempo máximo de espera de 5 segundos. El campo Evento dice de qué se trata; ignore los eventos que no reconozca (se añadirán nuevos manteniendo el formato).

EventoCuándo se envía¿Se aplica su respuesta?
mensaje-recibidoMensaje ENTRANTE: lo ha escrito el visitante (Emisor = 0).Sí.
mensaje-enviadoMensaje SALIENTE: lo ha escrito su agente, el asistente de IA o el sistema. Mire Emisor para saber cuál.No. Se le avisa para que lo registre, pero no se aplica nada: si no, sus propias respuestas dispararian otra respuesta y entraria en bucle.
pulsacion-chipEl visitante pulsa uno de los chips del mensaje, los [etiqueta|valor]. No navegan a ningún sitio: devuelven un valor a la conversación.Sí, siempre.
pulsacion-botonEl visitante pulsa un botón con enlace (un <a class="boton-chat">) de los marcados para seguir.Sí.
enlace-pulsadoEl visitante pulsa un enlace dentro del texto de los marcados para seguir.Sí.
encuesta-cierreEl visitante puntúa la atención con una carita de la encuesta de cierre.Sí.
conversacion-cerradaLa conversación se ha cerrado, por un agente o por su propia respuesta.No. Responder a un cierre reabriría la conversación de hecho, y si su script contesta siempre lo mismo, entraría en bucle.


Un apunte sobre los tres de pulsación, que es lo que suele costar entender: el chip no lleva URL y su valor vuelve a la conversación como respuesta del visitante; el botón y el enlace sí llevan URL y se le avisa cuando alguien los abre. Separarlos le deja medir qué funciona mejor sin cruzar dos cosas distintas en el mismo contador.

LA RESPUESTA DE SU SERVIDOR

Responda 2xx con un objeto JSON. Todos los campos son opcionales; si responde un cuerpo vacío no se hace nada:

CampoQué hace
responderTexto que se publica en la conversación como respuesta al visitante. Admite HTML básico y botones (ver abajo). Máximo 4.000 caracteres.
refReferencia suya (máx. 64 caracteres). Se guarda con el mensaje y vuelve en todos los eventos de pulsación cuando el visitante pulsa un chip, un botón o un enlace de ese mensaje. Es lo que le permite cruzar la pulsación con la petición que la originó.
htmlFuerza el tratamiento del texto: true lo interpreta como HTML aunque no se reconozca ninguna etiqueta, false lo deja como texto plano aunque las lleve. Si lo omite se decide solo (ver HTML).
cerrartrue cierra la conversación.
seguirtrue para saber cuándo el visitante abre los enlaces de este mensaje. Ver Seguimiento de enlaces.
estadisticaNombre con el que se agrupan los clics de este mensaje para poder contarlos (máx. 40 caracteres). Implica seguir.

SEGUIMIENTO DE ENLACES

Si quiere enterarse de cuándo alguien abre un enlace suyo, añada "seguir": true. Los enlaces de ese mensaje pasan a apuntar a un redirector nuestro que registra la pulsación y manda al destino, y usted recibe un evento pulsacion-boton o enlace-pulsado.



No se activa nunca por su cuenta, y hay una razón para que usted la valore: con el seguimiento puesto, el visitante ve nuestro dominio al pasar el ratón por encima, no el de destino. Para un enlace a una campaña suele dar igual; para un enlace a su propia web puede restarle confianza.



Enlace por enlace. Lo que ponga en el propio <a> manda sobre lo del mensaje, así que puede activar el seguimiento para todo y dejar uno concreto sin tocar:


       <a href="https://suweb.com/oferta" data-seguir="1" data-estadistica="oferta-verano">Ver la oferta</a>
       <a href="https://suweb.com/aviso-legal" data-seguir="0">Aviso legal</a>

Sirve igual en las respuestas rápidas que sus agentes tengan guardadas en el panel: basta con escribir el enlace con esos atributos.

ESTADÍSTICA DE CLICS

Los clics no se almacenan salvo que usted les ponga nombre, con "estadistica": "nombre" o con data-estadistica en el enlace. Sin nombre se le avisa del clic y no se guarda nada: acumular la navegación de sus visitantes sin que nadie lo haya pedido no aporta y son datos personales de por medio.



Use el mismo nombre en varios mensajes para agrupar una campaña entera.

BOTONES

Los botones se escriben dentro del propio texto de responder, con el formato [etiqueta|valor]:


- La etiqueta es lo que ve el visitante (normalmente un emoji, también vale texto).
- El valor es lo que le devolvemos a usted cuando lo pulsa.
- Se admiten hasta 10 botones por mensaje y los marcadores se quitan del texto que se muestra.
- El visitante sólo puede pulsar una vez por mensaje; después los botones quedan desactivados.



Aspecto: si ninguna etiqueta lleva letras ni números (es decir, son emojis o símbolos), los botones se pintan redondos y grandes, como las caritas de la encuesta. En cuanto una etiqueta lleva texto se pintan todos como botones normales. Es automático y no cambia el valor que se devuelve.


      Emojis  -> redondos:  "[😍|5][🙂|4][😐|3][🙁|2][😞|1]"
      Texto   -> normales:  "[Sí|si][No|no]"
      Mezcla  -> normales:  "[😍|5][Prefiero no contestar|x]"

Fuera del chat web no hay botones. En WhatsApp, SMS o email se envía sólo el texto, ya sin los marcadores.

HTML

El texto de responder admite HTML básico y siempre se sanea con una lista blanca antes de publicarlo:


- Etiquetas admitidas: b strong i em u s br p ul ol li a code small blockquote. Cualquier otra se descarta pero se conserva su texto.
- Se eliminan por completo (con su contenido) script, style, iframe, img, form y similares, y todos los atributos (style=, onclick=…).
- Los enlaces sólo admiten http, https, mailto y tel, y salen con target="_blank" y rel="noopener noreferrer nofollow".
- Si deja una etiqueta sin cerrar, se cierra sola: un HTML mal formado no rompe el mensaje.



El HTML no hay que pedirlo: si el texto trae alguna etiqueta de las admitidas, se sanea; si no, se trata como texto plano de siempre. Se hace así para que un mensaje corriente como "5 < 10" no se interprete como una etiqueta y pierda ese trozo. Con html puede forzar el criterio en cualquiera de los dos sentidos.



En WhatsApp, SMS o email se envía la versión en texto (los <br> pasan a saltos de línea y los enlaces a texto: url).

ENLACES CON ASPECTO DE BOT&Oacute;N

Los botones de [etiqueta|valor] devuelven el valor a su servidor, pero a veces lo que hace falta es simplemente llevar al visitante a una página. Para eso, añada la clase boton-chat a un enlace normal:


      {
        "responder": "<b>Elige tu plan</b><br>Selecciona una opción."
          + "<a href='https://tuweb.com/basico' class='boton-chat'>Plan básico</a>"
          + "<a href='https://tuweb.com/premium' class='boton-chat'>Plan premium</a>"
      }

Cada enlace se pinta como un botón de ancho completo, en su propia línea y centrado, con el color que el sitio tenga configurado en el chat (y su contraste, para que con un color claro el texto siga legible). Puede mezclarlos con el resto del HTML: negritas, listas o texto normal.



Diferencias con los botones [etiqueta|valor]:
- Abren una URL en una pestaña nueva; no le envían nada a su servidor ni generan el evento pulsacion-chip.
- No tienen límite de 10 ni se desactivan al pulsarlos: el visitante puede volver a usarlos.
- boton-chat es la única clase que sobrevive al saneado, y sólo en <a>. En cualquier otra etiqueta se descarta, y un enlace cuyo destino no sea http, https, mailto o tel pierde tanto el destino como el aspecto de botón.
- Fuera del chat web salen como el resto de enlaces: texto: url.

EJEMPLO COMPLETO: ENCUESTA CON REFERENCIA

1) El visitante escribe su último mensaje («gracias, ya está resuelto») y su servidor recibe mensaje-recibido. Responde con la encuesta y su referencia:


Ojo: la encuesta hay que lanzarla desde un mensaje-recibido. Con mensaje-enviado su respuesta no se aplica (ver la tabla de eventos), así que no sirve para reaccionar a que el agente cierre el chat; para eso está el botón de cerrar con encuesta del panel, que la manda solo.


      {
        "responder": "Por favor, valore cómo le hemos atendido<br/>[😍|5][🙂|4][😐|3][🙁|2][😞|1]",
        "ref": "12345AB"
      }

2) El visitante pulsa la primera carita y su servidor recibe el evento encuesta-cierre con su referencia, el valor pulsado y la ficha del visitante:


      {
        "Evento": "encuesta",  "idConversacion": 88,  "idMensaje": 1420,
        "Canal": "web",        "Valor": "5",         "Nota": 5,
        "Ref": "12345AB",      "idAgente": 7,        "Fecha": "2026-08-01 12:40:11",
        "Visitante": {
          "idVisitante": 12,   "Nombre": "Ana",  "Email": "ana@cliente.com",  "Telefono": "",
          "IP": "10.0.20.100", "UserAgent": "Mozilla/5.0...",
          "Url": "https://sutienda.com/carrito", "Idioma": "es", "Zona": "Europe/Madrid",
          "Pais": "Spain", "Ciudad": "Madrid", "Operadora": "Movistar",
          "Vars": { "pedido": "8812" },
          "idSitio": 3, "Canal": "web", "RefCanal": ""
        }
      }

3) Su servidor puede aún contestar algo a esa pulsación y cerrar:


      { "responder": "¡Gracias por su valoración!", "cerrar": true }

EJEMPLO: RECEPTOR EN PHP


      $esperado = 'Bearer mi_token_secreto';
      if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== $esperado) { http_response_code(401); exit; }

      $d = json_decode(file_get_contents('php://input'), true);
      header('Content-Type: application/json');

      // Pulsacion de un boton: se cruza con la referencia que enviamos antes
      if (($d['Evento'] ?? '') === 'encuesta') {
        guardaValoracion($d['Ref'], $d['Valor'], $d['Visitante']['Email'] ?? '');
        echo json_encode(['responder' => 'Gracias, lo tendremos en cuenta.', 'cerrar' => true]);
        exit;
      }

      // Mensaje del VISITANTE (Emisor 0). Con los del agente no se responde.
      if (($d['Evento'] ?? '') === 'mensaje-recibido') {
        if (stripos($d['Cuerpo'], 'pedido') !== false) {
          echo json_encode([
            'responder' => '<b>Pedido 881</b> enviado. ¿Le ayudo en algo mas? [Sí|si][No|no]',
            'ref'       => 'PED-881'
          ]);
          exit;
        }
      }

      echo '{}';   // no hacer nada: la conversacion sigue con el agente

basicAuth

Autenticación HTTP Basic. Use su Usuario API como usuario y su API Token como contraseña (los encuentra en su panel, en Tus Datos → Configurar Cuenta). El header resultante es Authorization: Basic base64(UsuarioAPI:APIToken). La mayoría de las librerías HTTP lo construyen automáticamente (curl -u, requests auth=, basic_auth de Ruby, etc.) sin necesidad de codificar el base64 a mano.

Security Scheme Type: HTTP
HTTP Authorization Scheme: basic

Petición que recibirá su servidor

https://{SuServidor}/script-receptor-en-su-servidor

PETICIÓN POST (JSON) QUE ENVIAMOS A SU URL EN CADA MENSAJE DEL CHAT.

Lleva la cabecera Authorization con el valor que haya configurado en el panel: compruébela y devuelva 401 si no cuadra. Responda 2xx con un JSON (ver «La respuesta de su servidor» en la Introducción) dentro de 5 segundos. Si no responde, la conversación continúa con normalidad y la atiende su agente.



Los campos marcados como propios de los eventos de pulsación (Valor, Nota, Ref, Visitante…) no llegan en los eventos de mensaje, y al revés.

Authorizations:
basicAuth
Request Body schema:

Parámetros recibidos en su script en petición POST con la configuración especificada en su panel de usuario/configuración API.

Evento
required
string

Qué ha pasado:
mensaje-recibido lo ha escrito el visitante
mensaje-enviado lo ha escrito su agente, el asistente de IA o el sistema
pulsacion-chip ha pulsado un chip [etiqueta|valor]
pulsacion-boton ha abierto un botón con enlace
enlace-pulsado ha abierto un enlace del texto
encuesta-cierre ha puntuado la atención con una carita
conversacion-cerrada se ha cerrado la conversación

Ignore los eventos que no reconozca: se añadirán nuevos manteniendo este formato.

idConversacion
required
integer

Identificador de la conversación. Es estable durante toda la conversación: úselo para agrupar los mensajes en su sistema.

Canal
required
string

Canal de origen de la conversación: web (widget de su web), whatsapp, sms, rcs o email. Los botones y el HTML sólo se ven en web.

idMensaje
required
integer

Identificador del mensaje. En los eventos de pulsación es el del mensaje que contenía los botones, no el de la pulsación.

Inicio
integer

Solo en los eventos de mensaje. 1 si es el PRIMER mensaje de la conversación, 0 si no. Le dice si tiene que abrir una ficha nueva en su sistema o añadir a una que ya existe, sin llevar la cuenta por su lado.

Motivo
string

Solo en conversacion-cerrada. Quién la cerró: agente (una persona desde el panel) o webhook (su propia respuesta con cerrar).

ConEncuesta
integer

Solo en conversacion-cerrada. 1 si al cerrar se le ha pedido al visitante que puntúe la atención. En ese caso aún le queda por llegar un evento encuesta-cierre, o no llegará nunca si no contesta: no dé el ticket por cerrado del todo hasta entonces.

Mensajes
integer

Solo en conversacion-cerrada. Número total de mensajes de la conversación.

Duracion
integer

Solo en conversacion-cerrada. Segundos entre el primer mensaje y el cierre.

Destino
string

Solo en pulsacion-boton y enlace-pulsado. La URL que ha abierto el visitante.

Estadistica
string

Solo en pulsacion-boton y enlace-pulsado. El nombre con el que usted agrupó ese enlace, si le puso alguno.

Emisor
integer

Sólo en los eventos de mensaje. Quién ha escrito: 0 visitante, 1 agente, 2 sistema, 3 asistente de IA. El sentido ya lo dice el propio Evento (0 es siempre mensaje-recibido); Emisor sirve para distinguir, dentro de lo enviado, si respondió una persona o el asistente de IA.

Cuerpo
string

Sólo en los eventos de mensaje. Texto del mensaje.

Valor
string

Sólo en los eventos de pulsación. El valor del botón pulsado, es decir la parte derecha de su [etiqueta|valor].

Nota
integer

Sólo en los eventos de pulsación. El mismo Valor convertido a número, o null si no lo era. Cómodo cuando los valores son notas del 1 al 5.

Texto
string

Sólo en los eventos de pulsación. La etiqueta del botón pulsado, tal como la vio el visitante (el emoji o el texto).

Ref
string

Sólo en los eventos de pulsación. La referencia que usted envió en el campo ref al mandar los botones. Cadena vacía si no envió ninguna.

Visitante
object

Sólo en los eventos de pulsación. Ficha de la persona que está chateando:
idVisitante - identificador estable del visitante en su cuenta.
Nombre, Email, Telefono - lo que haya dejado en el chat (vacío si no lo dio).
IP, UserAgent, Url - IP, navegador y página desde la que escribe.
Idioma, Zona - idioma del navegador y zona horaria.
Pais, Ciudad, Operadora - geolocalización por IP (puede venir vacía).
Vars - objeto con los campos propios que su sitio haya pedido en el formulario del chat.
idSitio, Canal, RefCanal - sitio de origen, canal e identificador del interlocutor en ese canal (teléfono o email; vacío en web).
FechaAlta, UltimaActividad - primera vez que le vimos y última actividad.

idAgente
integer

Sólo en los eventos de pulsación. Agente que tenía asignada la conversación (0 si la llevaba el titular o no estaba asignada). Útil para repartir la valoración por agente en sus propios informes.

Fecha
required
string

Fecha y hora del evento, en formato AAAA-MM-DD HH:MM:SS y hora peninsular española.

Request samples

Content type
{
  • "Evento": "mensaje-recibido",
  • "idConversacion": "88",
  • "Canal": "web",
  • "idMensaje": "1420",
  • "Inicio": "1",
  • "Motivo": "agente",
  • "ConEncuesta": "0",
  • "Mensajes": "14",
  • "Duracion": "842",
  • "Estadistica": "oferta-verano",
  • "Emisor": "0",
  • "Cuerpo": "Hola, quiero saber donde esta mi pedido",
  • "Valor": "5",
  • "Nota": "5",
  • "Texto": "😍",
  • "Ref": "12345AB",
  • "Visitante": "{ \"idVisitante\": 12, \"Nombre\": \"Ana\", \"Email\": \"ana@cliente.com\", \"IP\": \"10.0.20.100\", \"Pais\": \"Spain\", \"Vars\": { \"pedido\": \"8812\" } }",
  • "idAgente": "7",
  • "Fecha": "2026-08-01 12:40:11"
}