Saltar al contenido principal
Usa estos endpoints para conectar Visito con un CRM, helpdesk o backend de operaciones. La URL base es:
Envía Authorization: Bearer <token> desde el servidor. Consulta Autenticación para scopes, errores e idempotencia.

Endpoints

Listar y leer conversaciones

GET /conversations devuelve una lista paginada. Envía nextCursor como el parámetro cursor con los mismos filtros para obtener la siguiente página; limit acepta de 1 a 200. Termina cuando hasMore=false; entonces se omite nextCursor. El orden es por fecha del último mensaje descendente y, en empates, por ID de conversación ascendente. La lista es en vivo: los mensajes nuevos pueden mover una conversación antes del cursor. Actualiza la primera página y elimina IDs duplicados al combinar páginas. Un cursor inválido devuelve 400 M2M_INVALID_REQUEST. GET /conversations/{conversationId} devuelve solo metadatos. El campo conversation.needsReply es la única señal autoritativa de que se requiere acción; lastMessageRole solo describe la cronología. Para consultar únicamente los contactos que se dieron de baja mediante un comando STOP de WhatsApp compatible, usa GET /conversations?optedOut=true. La respuesta incluye optedOut, optedOutAt y optedOutReason; usa el identificador del participante para excluir al contacto correspondiente en tu sistema de campañas. Visito seguirá bloqueando los envíos a una conversación dada de baja aunque tu sincronización externa se retrase. GET /conversations/{conversationId}/messages devuelve el historial externo ordenado del más reciente al más antiguo. Usa limit y el cursor opaco de nextCursor para consultar mensajes anteriores. hasMore=true significa que quedan mensajes externos anteriores y nextCursor es null al terminar. Los eventos internos system y tool no forman parte de este recurso.

Enviar una respuesta

Incluye un Idempotency-Key estable en cada envío:
La respuesta 202 Accepted indica que el envío está en cola, no entregado. Guarda conversationId, replyId, requestEventId, correlationId e Idempotency-Key y vuelve a leer /conversations/{conversationId}/messages para reconciliar requestEventId con messages[].eventId.
Reintenta un envío únicamente con el mismo cuerpo y la misma clave de idempotencia. No expongas el token en frontend o apps móviles.
Cuando la ventana de respuesta de WhatsApp esté cerrada, utiliza una plantilla aprobada.

Pausa automática de la IA (auto-freeze)

Las respuestas aceptadas heredan la preferencia del negocio en Configuración → Personalización → Ajustes del asistente → Pausar la IA después de una respuesta del equipo. Los administradores pueden elegir Desactivado, 15 minutos, 30 minutos, 1 hora o 2 horas, también desde Personalización → Ajustes del asistente en iOS y Android. Sin una preferencia guardada se conserva el valor del servidor (normalmente 30 minutos). Aplica a texto, adjuntos con mediaId y adjuntos por URL. Cada respuesta aceptada reinicia el temporizador elegido. Cambiar la preferencia afecta respuestas futuras, sin modificar pausas existentes. Los mensajes automáticos del asistente no generan una pausa de operador. Omite autoFreeze para heredar la preferencia. Para cambiarla en una sola respuesta:
minutes acepta enteros de 1 a 120. Para no crear ni extender una pausa:
Desactivado conserva cualquier pausa existente; no reanuda la IA. Los cambios de pausa se aplican de forma asíncrona tras aceptar la respuesta, sin esperar la preparación del adjunto ni la entrega. Repetir el mismo Idempotency-Key no reinicia el temporizador; la recuperación usa la decisión y hora originales.

Consultar el vencimiento y reanudar la IA

Los objetos de conversación en listado y detalle incluyen el campo opcional frozenUntilAt (fecha ISO). Permite mostrar “IA en pausa hasta…”. GET /conversations/{conversationId}/policy también devuelve isFrozen y frozenSecondsRemaining (conversations:read). La acción Resolver de tu integración puede terminar la pausa con el permiso conversations:policy:write:
El mismo endpoint acepta {"freezeForMinutes":120} para establecer una pausa. No lo combines con unfreeze:true. No existe un endpoint /unfreeze separado. Terminar la pausa no elimina el modo Manual, bloqueos ni escalamientos abiertos; resuelve primero cualquier escalamiento mediante su flujo correspondiente.
Los clientes antiguos que usan autoFreeze.enabled conservan su comportamiento: enabled:false termina la pausa. Las integraciones nuevas y apps actualizadas deben usar mode; no combines mode y enabled.

Adjuntos por URL

Los adjuntos por URL están disponibles por defecto en los canales compatibles con el permiso conversations:write. Usa el mismo endpoint /conversations/{conversationId}/reply, token e Idempotency-Key:
No necesitas subir el archivo previamente. Usa un solo media o un mediaId existente, nunca ambos. filename es opcional. No existe una ruta M2M de subida multipart. Para una imagen: {"media":{"type":"image","url":"https://files.example.com/foto.jpg"}}. Para audio: {"media":{"type":"audio","url":"https://files.example.com/audio.mp3"}}. Para una nota de voz de WhatsApp: {"media":{"type":"audio","url":"https://files.example.com/voz.ogg","voice":true}}. text acompaña imágenes, videos y documentos; en WhatsApp se usa como caption y en Instagram/Messenger puede enviarse por separado. WhatsApp no admite audio más text en esta petición. voice solo aplica a audio. No se transcodifican archivos. Webchat queda fuera de esta versión. Las combinaciones no soportadas se rechazan con 400 REPLY_MEDIA_COMBINATION_UNSUPPORTED, sin sustituir el archivo por un enlace. La URL debe devolver el archivo por HTTPS público, puerto 443, sin cookies ni headers de autenticación. Puede ser una URL firmada, vigente durante la preparación y sus reintentos. Se rechazan destinos privados e IPv6; se validan hasta tres redirecciones. La descarga tiene un límite de 30 segundos y se comprueba el tamaño real recibido. VISITO valida y conserva una copia antes de enviar. 202 significa aceptado y en cola, no entregado. Guarda replyId y requestEventId y consulta el estado de entrega y el historial. Después de guardar la copia, los reintentos de entrega no dependen de la URL original. Los fallos posteriores de descarga, formato, tamaño o almacenamiento marcan la respuesta como fallida y no envían texto como sustituto. El proveedor puede rechazar detalles del codec o archivos malformados tras la validación inicial. Los errores de preparación incluyen un errorCode saneado en el estado del mensaje o solicitud. REPLY_MEDIA_SOURCE_CHANGED indica que la URL cambió de contenido durante la preparación; no se sustituye el archivo elegido inicialmente. Consulta los ejemplos y errores detallados. Al reintentar una petición, conserva su body y Idempotency-Key originales. Consulta Operaciones diarias para búsquedas, seguimientos, revisiones, inicio de WhatsApp, reservas y configuración de mensajes.