Skip to content

Consultar Historial de Servicios

Endpoint

POST /api/v3/queries/history

Descripción

Permite realizar consultas históricas de servicios con múltiples filtros y criterios de búsqueda. Es útil para reportes, auditorías y análisis operacional.

La consulta se resuelve de dos formas según la línea de negocio (line):

  • Cuando line es distinto de "2", se consulta sobre servicios.
  • Cuando line es "2", se consulta sobre tareas (la estructura de cada registro varía ligeramente; ver Diferencias para line = "2").

Caché

Los resultados se almacenan en caché durante 1 hora. Si no hubo cambios en los datos desde la última consulta cacheada, la respuesta incluye el mensaje Datos obtenidos correctamente (cached). Puedes forzar la recarga enviando invalidateCache: true en el body.

Autenticación

Este endpoint usa autenticación básica HTTP (autValidator). Consulta la guía de autenticación para más detalles.

Authorization: Basic <credentials>

Parámetros de Entrada

Body (JSON)

CampoTipoRequeridoDescripción
linestringLínea de negocio a consultar. Internamente se convierte a entero. Con "2" se consulta sobre tareas.
startDatestringCondicionalFecha de inicio en formato YYYY-MM-DD HH:MM.
endDatestringCondicionalFecha de fin en formato YYYY-MM-DD HH:MM.
autNumberstringNoNúmero de autorización (búsqueda parcial, LIKE).
movNumberstringNoNúmero de movimiento (búsqueda parcial, LIKE).
licencePlatestringNoPlaca del vehículo (búsqueda parcial, LIKE).
creatorstringNoUsuario creador del servicio (búsqueda parcial, LIKE).
businessNitarrayNoLista de NITs de empresas a filtrar.
serviceStatusarrayNoLista de estados de servicio a filtrar.
serviceTypearrayNoLista de tipos de servicio a filtrar.
closeStatusarrayNoLista de estados de cierre a filtrar.
resourseIdarrayNoLista de IDs de recursos/técnicos. Nota: el nombre del campo es resourseId (así está en el código). Tiene prioridad sobre providerNit para filtrar el recurso.
providerNitarrayNoLista de NITs de prestadores. Solo se aplica si resourseId está vacío.
invalidateCachebooleanNoSi es true, invalida el caché y consulta directamente la base de datos.

Requisito mínimo de búsqueda

Además de line, debes proporcionar un rango de fechas (startDate + endDate) o al menos uno de los campos autNumber, movNumber, licencePlate o creator. Si no se cumple, la API responde 400.

Reglas de validación

CondiciónCódigoMensaje (msg)
Falta line400La línea de negocio es requerida.
No hay fechas ni ningún identificador (autNumber, movNumber, licencePlate, creator)400Debe proporcionar un rango de fechas o al menos uno de los siguientes campos: autNumber, movNumber, licencePlate o creator.
startDate mayor que endDate400La fecha de inicio no puede ser mayor que la fecha de fin.
Formato de fecha inválido400El formato de fecha debe ser YYYY-MM-DD HH:MM.
No se encuentra la central del usuario404Central no encontrada.

Ejemplos de Request

Búsqueda por Número de Autorización

json
{
  "line": "1",
  "autNumber": "TSV12345678"
}

Búsqueda por Rango de Fechas

json
{
  "line": "1",
  "startDate": "2025-07-01 00:00",
  "endDate": "2025-07-03 23:59"
}

Búsqueda con Filtros Múltiples

json
{
  "line": "1",
  "startDate": "2025-07-01 00:00",
  "endDate": "2025-07-01 23:59",
  "businessNit": ["901666", "556989"],
  "serviceStatus": ["3", "5"],
  "serviceType": ["1", "2"],
  "providerNit": ["900123456"]
}

Respuestas

Éxito (200 Correcto)

La respuesta es un objeto con status, data (arreglo de registros) y msg. No hay metadatos de paginación: data contiene todos los registros que coinciden con los filtros.

json
{
  "status": true,
  "data": [
    {
      "autNumber": "TSV12345678",
      "movNumber": "MOV001",
      "line": "Grúas",
      "serviceId": 1024,
      "serviceType": {
        "id": 1,
        "name": "Grúa Liviana"
      },
      "serviceStatus": "Finalizado",
      "closeStatus": "Cerrado",
      "client_name": "Carlos Rodríguez",
      "cellphone": "3001234567",
      "alternPhone": "3019876543",
      "vhType": "Automóvil",
      "vhModel": "2020",
      "serviceDateTime": "2025-07-03 10:30",
      "vhLicence": "ABC123",
      "stimatedFinishDate": "2025-07-03 12:00",
      "finishDate": "2025-07-03 12:45",
      "s_price": 95000,
      "s_price_additionals": 0,
      "s_final_price": 95000,
      "ligthComments": null,
      "additionals_service": [],
      "resource_additions": [],
      "resource_payment": 70000,
      "map_distance": 12.5,
      "standard_distance": 12,
      "cashToCollect": 0,
      "satisfaction": null,
      "business": {
        "nit": "901666",
        "name": "Aseguradora XYZ",
        "subacount": null
      },
      "resourceType": "own",
      "resource": {
        "id": "TECH001",
        "names": "Carlos Rodríguez",
        "phone": "6011234567",
        "cellphone": "3001234567",
        "email": "carlos@tsalva.com",
        "coords": {
          "lat": 4.65,
          "lng": -74.05,
          "speed": 0,
          "lastUpdate": "2025-07-03 12:45"
        }
      },
      "tasks": [
        {
          "taskype": "Recogida",
          "vinculated_to_task": null,
          "taskNumber": "T-001",
          "taskAddress": "Autopista Norte Km 15",
          "addressMap": "Autopista Norte Km 15, Bogotá",
          "taskStatus": "Completado",
          "taskCoords": {
            "lat": 4.7,
            "lng": -74.05
          },
          "instructions": "Vehículo averiado, carril derecho",
          "city": {
            "city": "Bogotá",
            "dpto": "Cundinamarca",
            "country": "Colombia"
          }
        }
      ]
    }
  ],
  "msg": "Datos obtenidos correctamente"
}

Respuesta cacheada

Cuando los datos provienen del caché y no hubo cambios, msg es Datos obtenidos correctamente (cached).

Campos del registro

CampoTipoDescripción
autNumberstringNúmero de autorización del servicio.
movNumberstringNúmero de movimiento.
linestringNombre de la línea de negocio (line_name).
serviceIdnumberIdentificador del servicio.
serviceTypeobject{ id, name } del tipo de servicio.
serviceStatusstringNombre del estado del servicio.
closeStatusstringNombre del estado de cierre (Desconocido si no se resuelve).
client_namestringNombre del cliente.
cellphonestringCelular del cliente.
alternPhonestringTeléfono alterno del cliente.
vhTypestringTipo de vehículo.
vhModelstringModelo del vehículo.
serviceDateTimestringFecha/hora del servicio.
vhLicencestringPlaca del vehículo.
stimatedFinishDatestringFecha estimada de finalización.
finishDatestringFecha real de finalización.
s_pricenumberPrecio base del servicio.
s_price_additionalsnumberPrecio de adicionales.
s_final_pricenumberPrecio final.
ligthCommentsstringJustificación de excedente (s_exeed_just).
additionals_servicearrayAdicionales del servicio.
resource_additionsarrayAdicionales del recurso.
resource_paymentnumberPago al recurso.
map_distancenumberDistancia según mapa.
standard_distancenumberDistancia estándar.
cashToCollectnumberEfectivo a recaudar.
satisfactionnumberCalificación de satisfacción.
businessobject{ nit, name, subacount } de la empresa.
resourceTypestringown, provider o unknown.
resourceobjectDatos del recurso asignado (ver abajo).
tasksarrayTareas asociadas (ver abajo).

Objeto resource según resourceType

  • own (técnico propio): { id, names, phone, cellphone, email, coords: { lat, lng, speed, lastUpdate } }
  • provider (prestador): { nit, central, phone, cellphone, email, resource: { id, names, phone, cellphone, coords } } (resource es {} si el prestador no tiene técnico asignado).
  • unknown (sin recurso): { id: "0", names: "Sin recurso asignado" }

Objeto de cada elemento de tasks

CampoDescripción
taskypeNombre del tipo de tarea.
vinculated_to_taskTarea vinculada (o null).
taskNumberNúmero de tarea.
taskAddressDirección de la tarea.
addressMapDirección normalizada (task_address_trad).
taskStatusNombre del estado de la tarea.
taskCoords{ lat, lng }.
instructionsInstrucciones de la tarea.
city{ city, dpto, country }.

Diferencias para line = "2"

Cuando line es "2" la consulta se hace sobre tareas y cada registro tiene variaciones respecto a la estructura anterior:

  • serviceType es un string (nombre del tipo) en lugar de un objeto { id, name }.
  • serviceDateTime proviene de task_date, stimatedFinishDate de task_date_end y finishDate de task_finish_date.
  • cashToCollect proviene de task_cash.
  • Para un recurso propio (own), el objeto resource usa id: techId; para un prestador (provider) es { id, names, phone, cellphone, email, coords }; sin recurso es { names: "Sin recurso asignado" }.

Error de validación (400)

json
{
  "status": false,
  "msg": "La línea de negocio es requerida."
}

Central no encontrada (404)

json
{
  "status": false,
  "msg": "Central no encontrada."
}

Error interno (500)

json
{
  "status": false,
  "msg": "Error interno del servidor",
  "error": "Detalle del error"
}

Ejemplos de Código

cURL

bash
# Por número de autorización
curl -X POST "[URL_API]/api/v3/queries/history" \
  --user "$TSALVA_USERNAME:$TSALVA_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{
    "line": "1",
    "autNumber": "TSV12345678"
  }'

# Por rango de fechas
curl -X POST "[URL_API]/api/v3/queries/history" \
  --user "$TSALVA_USERNAME:$TSALVA_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{
    "line": "1",
    "startDate": "2025-07-01 00:00",
    "endDate": "2025-07-03 23:59"
  }'

JavaScript

javascript
const consultarHistorial = async (criterios) => {
  const response = await fetch('[URL_API]/api/v3/queries/history', {
    method: 'POST',
    headers: {
      'Authorization': `Basic ${btoa('usuario:password')}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(criterios)
  });

  const result = await response.json();

  if (!result.status) {
    throw new Error(result.msg || 'Error en consulta');
  }

  return result.data;
};

// Ejemplos de uso
try {
  // Historial por autorización
  const porAutorizacion = await consultarHistorial({
    line: '1',
    autNumber: 'TSV12345678'
  });

  // Historial del día actual
  const hoy = new Date().toISOString().split('T')[0];
  const porFecha = await consultarHistorial({
    line: '1',
    startDate: `${hoy} 00:00`,
    endDate: `${hoy} 23:59`
  });

  // Historial con filtros
  const conFiltros = await consultarHistorial({
    line: '1',
    startDate: '2025-07-01 00:00',
    endDate: '2025-07-01 23:59',
    serviceStatus: ['3'],
    serviceType: ['1']
  });

  console.log('Registros encontrados:', conFiltros.length);
} catch (error) {
  console.error('Error:', error.message);
}

Python

python
import requests
from requests.auth import HTTPBasicAuth
from datetime import datetime, timedelta

def consultar_historial(criterios):
    response = requests.post(
        '[URL_API]/api/v3/queries/history',
        auth=HTTPBasicAuth('usuario', 'password'),
        json=criterios
    )

    result = response.json()

    if not result['status']:
        raise Exception(result.get('msg', 'Error en consulta'))

    return result['data']

# Ejemplos de uso
try:
    # Historial de los últimos 7 días
    fin = datetime.now()
    inicio = fin - timedelta(days=7)

    historial = consultar_historial({
        'line': '1',
        'startDate': inicio.strftime('%Y-%m-%d %H:%M'),
        'endDate': fin.strftime('%Y-%m-%d %H:%M'),
        'serviceStatus': ['3']
    })

    print(f"Servicios encontrados en los últimos 7 días: {len(historial)}")

    for servicio in historial:
        print(f"ID: {servicio['serviceId']}")
        print(f"Estado: {servicio['serviceStatus']}")
        print(f"Empresa: {servicio['business']['name']}")
        print("---")

except Exception as e:
    print(f"Error: {e}")

Rendimiento

Para consultas de grandes volúmenes, usa filtros específicos (estado, tipo, empresa) y divide el rango de fechas en períodos más pequeños. Recuerda que los IDs de estado y tipo de servicio válidos se obtienen con Opciones de historial.

Referencias

Tsalva API - Documentación desarrollada por RobPixels