Esta guía documenta el acceso a la API del sistema. El objetivo es que un desarrollador pueda integrarse solo con URL base + usuario + contraseña + esta documentación.
La autenticación es por POST JSON y el flujo normal es:
Obtener token y hash del catálogo.
Obtener catálogo completo o filtrado.
Consultar disponibilidad.
Crear reserva.
Cancelar reserva (opcional).
Logout.
Convenciones básicas
Formato
application/json; charset=utf-8
Fechas
YYYYMMDD p.ej. 20251013
Horas
HHMM p.ej. 1430 → 14:30
Trazabilidad
t_init / t_end sellos de tiempo del servidor
Catálogo
Define combinaciones válidas.
Disponibilidad
Define qué combinaciones válidas están libres en un intervalo concreto.
Estrategia de integración
Hacer login y guardar tkn y catalogo_hash.
Si no existe catálogo local o el hash cambió, volver a solicitar y almacenar el catálogo.
Usar el catálogo para traducir dimensiones y registros a IDs operativos.
Consultar disponibilidad con una selection parcial que represente el filtro de negocio.
Elegir una entrada disponible en disponibilidad[fecha][indice].
Tomar seleccion[indice] y revisar catalogo.agendas para obtener las combinaciones completas que calzan con esa selección.
Elegir la combinación final y crear el ticket con selectionId.
Punto clave: las agendas siempre son distintas entre sí. En el ejercicio automotriz las diferencias se entienden muy bien a través del modelo del vehículo, pero en otro sistema podrían diferir por cualquier otra dimensión del catálogo.
Ejercicio guiado paso a paso
Objetivo: crear un ticket para un Mantenimiento en Sucursal Las Condes para un vehículo Citroën, escogiendo un horario realmente disponible.
Este ejercicio es automotriz porque ayuda a entender los conceptos, pero la misma lógica aplica aunque las dimensiones de una agenda real sean otras.
Lectura: la selección parcial consultada fue [1048,482,684], pero el sistema devolvió una selección disponible más completa. Además, catalogo.agendas indica qué combinaciones completas del catálogo contienen esa selección disponible.
Paso 6. Elegir la combinación completa
Tomando los IDs en catalogo.agendas, se revisa en el catálogo qué valor toma la dimensión 4 = Vehículo para cada uno.
Supongamos que, después de ese cruce, se elige selectionId = 322, correspondiente al modelo CACTUS.
El integrador debe persistir el valor retornado en appointmentIds. Ese ID será usado, por ejemplo, para cancelación posterior.
Preguntas frecuentes
1. Si consulto disponibilidad con una selección parcial, por qué me devuelve varias agendas?
Porque tu selección inicial puede estar contenida en múltiples combinaciones completas del catálogo. catalogo.agendas representa justamente esas combinaciones completas candidatas.
2. Si la respuesta de disponibilidad trae más de una selección (por ejemplo, 0 y 1), qué significa?
Significa que el sistema encontró más de una selección disponible que satisface tu filtro. Cada una debe analizarse por separado: tiene sus propios bloques horarios y su propio conjunto de agendas candidatas.
3. Significa que las agendas en catalogo.agendas son iguales?
No. Las agendas siempre son distintas entre sí. Lo que ocurre es que todas contienen la selección parcial encontrada disponible. Se diferencian en una o más dimensiones que no estaban fijadas en tu filtro inicial.
4. En el ejemplo se habla de modelos de vehículo. Eso siempre será así?
No. En el ejemplo automotriz la diferencia entre agendas se entiende muy bien a través del modelo del vehículo, pero en otros catálogos las agendas pueden diferir por cualquier otra dimensión.
5. Cuál es la diferencia entre catálogo y disponibilidad?
El catálogo enumera combinaciones válidas. La disponibilidad indica cuáles de esas combinaciones están realmente libres en un intervalo concreto.
6. Una agenda puede seguir existiendo en el catálogo aunque ya no esté libre?
Sí. Sigue existiendo como combinación válida, pero deja de aparecer como disponible en los intervalos que intersectan una reserva ya tomada.
7. Cuándo debo volver a pedir el catálogo?
Cuando no tengas una copia local o cuando el catalogo_hash entregado en el login sea distinto al hash almacenado.
8. Para qué sirve selected_dimensions en get_catalogo?
Permite solicitar solo una proyección del catálogo sobre ciertas dimensiones. Es útil, por ejemplo, para obtener solo relaciones Marca|Vehículo.
9. Para qué sirve selection en get_catalogo?
Permite filtrar el catálogo por ciertos registros específicos. En este endpoint se admite más de un valor por dimensión.
10. Por qué la documentación usa selectionId para crear la reserva?
Porque el código vigente revisado crea el ticket a partir de selectionId. Aunque históricamente hubo ejemplos con agenda_id, la documentación debe seguir lo que realmente implementa el código.
11. Qué debo guardar localmente en mi integración?
Como mínimo: el catálogo, su hash, los IDs relevantes de dimensiones/registros, y los appointmentIds de tickets creados.
12. Si consulto la auditoría por un appointment_id, por qué pueden aparecer otros tickets?
Porque el appointment_id se utiliza para identificar la sesión de trabajo en la que fue creado el ticket. La respuesta devuelve todas las comunicaciones auditadas de esa sesión, representada por su token de acceso. Si durante la misma sesión se crearon otros tickets, sus interacciones también aparecerán.
Permite recuperar las comunicaciones auditadas de una sesión buscando por su token de acceso o por el appointment_id de un ticket creado durante esa sesión. Este valor corresponde a uno de los IDs retornados en appointmentIds al crear un ticket.
La API registra las solicitudes y respuestas realizadas por los distintos clientes integrados. Esta información permite reconstruir qué ocurrió durante una sesión de trabajo y analizar, entre otras cosas, consultas de catálogo, disponibilidad, creación de tickets, cancelaciones, respuestas y excepciones.
Operación disponible
Tipo de mensaje
booking_audit_get_json_messages
Método
POST
URL
[url_base]/ws/mab_web_service
Autorización
Se envía en tkn, igual que en las demás operaciones autenticadas.
tkn es el token que autoriza a quien está realizando la consulta de auditoría.
search_by_access_token es el token histórico de la sesión que se desea investigar.
Ambos valores pueden ser distintos: uno autoriza la consulta y el otro identifica la sesión auditada.
Criterios de búsqueda
En cada solicitud se deben enviar solamente los criterios que realmente se utilizarán. Si se busca por appointment_id, se omite search_by_access_token. Si se busca por token, se omite search_by_appointment_id. No es necesario enviar el criterio no utilizado con valor null.
1. Buscar por token de acceso
Devuelve todas las comunicaciones auditadas asociadas al token indicado en search_by_access_token, ordenadas cronológicamente por el instante de entrada de cada solicitud.
2. Buscar por appointment_id
El valor enviado en search_by_appointment_id corresponde a uno de los IDs retornados en appointmentIds al crear un ticket. Se utiliza para localizar la sesión en la que fue creado ese ticket. Una vez identificada la sesión, la API devuelve todas las comunicaciones auditadas asociadas al token de acceso de esa sesión.
Importante: una búsqueda por appointment_id no devuelve un historial exclusivo de ese ticket. Devuelve el historial completo de la sesión en la que fue creado. Si el mismo token se utilizó para crear más de un ticket, la respuesta puede incluir interacciones correspondientes a esos otros tickets. Esto es esperado y no representa una mezcla accidental de auditorías.
La interpretación correcta es:
appointment_id consultado
→ identifica la sesión de creación
→ identifica el token de acceso de esa sesión
→ recupera todas las comunicaciones conocidas de ese token
3. Buscar utilizando ambos criterios
Cuando se envían simultáneamente search_by_access_token y search_by_appointment_id, ambos criterios se combinan mediante una condición lógica AND. En otras palabras, el ticket identificado por appointment_id debe haber sido creado en la sesión representada por el token indicado.
Si el token existe y el ticket existe, pero el ticket fue creado en otra sesión, la respuesta será válida y contendrá messages: [], porque no existe una coincidencia que satisfaga ambos criterios.
4. Consulta sin criterios
Se debe proporcionar al menos uno de los dos criterios de búsqueda. Si ambos se omiten, la operación no consulta el historial y la respuesta contiene una lista messages vacía.
La respuesta contiene una lista messages. Cada elemento representa una interacción completa y agrupa la solicitud original en request y la respuesta del servidor en response.
request.t
Instante en que se recibió la solicitud.
request.json
Solicitud interpretada como objeto JSON, cuando el contenido almacenado era JSON válido.
request.msg
Texto original, utilizado cuando el contenido no pudo interpretarse como JSON.
response.t
Instante en que se registró la respuesta.
response.json
Respuesta interpretada como objeto JSON, cuando corresponde.
response.msg
Respuesta como texto cuando no corresponde a JSON válido.
response.exception
Excepción registrada durante el procesamiento, si existió.
El siguiente ejemplo es ilustrativo. El ticket consultado es 116326, pero la misma sesión también creó el ticket 116327; por eso ambas operaciones aparecen en el historial:
Cómo leer el ejemplo: la consulta se originó a partir del ticket 116326, pero el resultado representa la sesión completa. La presencia del ticket 116327 indica que fue creado utilizando el mismo token de acceso durante esa sesión.
Mensajes JSON y mensajes de texto
Cuando el contenido auditado es JSON válido, se entrega en el campo json como una estructura navegable. Cuando no es JSON válido, json será null y el contenido original se entregará en msg.
{
"t":1760290100000,
"json":null,
"msg":"Internal Server Error",
"exception":"java.lang.Exception: error procesando la solicitud"
}