Apariencia
Consultar Historial de Servicios
Endpoint
POST /api/v3/queries/historyDescripció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
linees distinto de"2", se consulta sobre servicios. - Cuando
linees"2", se consulta sobre tareas (la estructura de cada registro varía ligeramente; ver Diferencias paraline = "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)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
line | string | Sí | Línea de negocio a consultar. Internamente se convierte a entero. Con "2" se consulta sobre tareas. |
startDate | string | Condicional | Fecha de inicio en formato YYYY-MM-DD HH:MM. |
endDate | string | Condicional | Fecha de fin en formato YYYY-MM-DD HH:MM. |
autNumber | string | No | Número de autorización (búsqueda parcial, LIKE). |
movNumber | string | No | Número de movimiento (búsqueda parcial, LIKE). |
licencePlate | string | No | Placa del vehículo (búsqueda parcial, LIKE). |
creator | string | No | Usuario creador del servicio (búsqueda parcial, LIKE). |
businessNit | array | No | Lista de NITs de empresas a filtrar. |
serviceStatus | array | No | Lista de estados de servicio a filtrar. |
serviceType | array | No | Lista de tipos de servicio a filtrar. |
closeStatus | array | No | Lista de estados de cierre a filtrar. |
resourseId | array | No | Lista 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. |
providerNit | array | No | Lista de NITs de prestadores. Solo se aplica si resourseId está vacío. |
invalidateCache | boolean | No | Si 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ón | Código | Mensaje (msg) |
|---|---|---|
Falta line | 400 | La línea de negocio es requerida. |
No hay fechas ni ningún identificador (autNumber, movNumber, licencePlate, creator) | 400 | Debe proporcionar un rango de fechas o al menos uno de los siguientes campos: autNumber, movNumber, licencePlate o creator. |
startDate mayor que endDate | 400 | La fecha de inicio no puede ser mayor que la fecha de fin. |
| Formato de fecha inválido | 400 | El formato de fecha debe ser YYYY-MM-DD HH:MM. |
| No se encuentra la central del usuario | 404 | Central 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
| Campo | Tipo | Descripción |
|---|---|---|
autNumber | string | Número de autorización del servicio. |
movNumber | string | Número de movimiento. |
line | string | Nombre de la línea de negocio (line_name). |
serviceId | number | Identificador del servicio. |
serviceType | object | { id, name } del tipo de servicio. |
serviceStatus | string | Nombre del estado del servicio. |
closeStatus | string | Nombre del estado de cierre (Desconocido si no se resuelve). |
client_name | string | Nombre del cliente. |
cellphone | string | Celular del cliente. |
alternPhone | string | Teléfono alterno del cliente. |
vhType | string | Tipo de vehículo. |
vhModel | string | Modelo del vehículo. |
serviceDateTime | string | Fecha/hora del servicio. |
vhLicence | string | Placa del vehículo. |
stimatedFinishDate | string | Fecha estimada de finalización. |
finishDate | string | Fecha real de finalización. |
s_price | number | Precio base del servicio. |
s_price_additionals | number | Precio de adicionales. |
s_final_price | number | Precio final. |
ligthComments | string | Justificación de excedente (s_exeed_just). |
additionals_service | array | Adicionales del servicio. |
resource_additions | array | Adicionales del recurso. |
resource_payment | number | Pago al recurso. |
map_distance | number | Distancia según mapa. |
standard_distance | number | Distancia estándar. |
cashToCollect | number | Efectivo a recaudar. |
satisfaction | number | Calificación de satisfacción. |
business | object | { nit, name, subacount } de la empresa. |
resourceType | string | own, provider o unknown. |
resource | object | Datos del recurso asignado (ver abajo). |
tasks | array | Tareas 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 } }(resourcees{}si el prestador no tiene técnico asignado).unknown(sin recurso):{ id: "0", names: "Sin recurso asignado" }
Objeto de cada elemento de tasks
| Campo | Descripción |
|---|---|
taskype | Nombre del tipo de tarea. |
vinculated_to_task | Tarea vinculada (o null). |
taskNumber | Número de tarea. |
taskAddress | Dirección de la tarea. |
addressMap | Dirección normalizada (task_address_trad). |
taskStatus | Nombre del estado de la tarea. |
taskCoords | { lat, lng }. |
instructions | Instrucciones 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:
serviceTypees un string (nombre del tipo) en lugar de un objeto{ id, name }.serviceDateTimeproviene detask_date,stimatedFinishDatedetask_date_endyfinishDatedetask_finish_date.cashToCollectproviene detask_cash.- Para un recurso propio (
own), el objetoresourceusaid: 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
- Opciones de historial - Obtener los valores válidos para los filtros.
- Autenticación - Configuración de credenciales.
- Códigos de Respuesta - Manejo de errores estándar.