Apariencia
Crear Oferta de Servicio
Endpoint
POST /api/v3/ofertaDescripción
Crea una nueva oferta de servicio en el sistema TSALVA. La oferta se evalúa y se distribuye automáticamente a las centrales y técnicos habilitados con cobertura en la ubicación de origen. Cuando un técnico responde y su oferta es aceptada, TSALVA notifica el resultado a tu servidor mediante el webhook de aceptación de oferta.
Funcionalidad
- Registra una nueva solicitud de servicio y la almacena para su evaluación.
- Acepta el origen por coordenadas o por dirección (se geocodifica automáticamente).
- Distribuye la oferta a centrales y técnicos con cobertura.
- Notifica la aceptación mediante el webhook de aceptación.
Autenticación
Este endpoint usa autenticación HTTP Basic (autValidator). Consulta Autenticación para el detalle de errores 401 / 403.
Authorization: Basic <credentials>Parámetros de Entrada
Headers
Content-Type: application/json
Authorization: Basic <credentials>Body (JSON)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
uuid | string (UUID) | Sí | Identificador único de la oferta. Si el UUID ya está siendo ofertado, se rechaza la petición. |
tipoServicio | string | Sí | Tipo de servicio solicitado. Admite un ID o una lista separada por comas (se usa el primero). Consulta GET /api/v3/types. |
latitudOrigen | number | Condicional | Latitud del origen (decimal). Requerida si no envías direccionOrigen. |
longitudOrigen | number | Condicional | Longitud del origen (decimal). Requerida si no envías direccionOrigen. |
direccionOrigen | string | Condicional | Dirección de origen. Se geocodifica si no envías coordenadas válidas; en ese caso también se completan automáticamente ciudad y departamento. |
descripcionServicio | string | No | Descripción del servicio. Si se omite, se usa el nombre del tipoServicio o "SERVICIO NO ESPECIFICADO". |
puntoReferenciaOrigen | string | No | Referencia del lugar de origen. |
direccionDestino | string | No | Dirección de destino. Si la envías sin coordenadas válidas, se geocodifica. |
latitudDestino | number | No | Latitud del destino (decimal). |
longitudDestino | number | No | Longitud del destino (decimal). |
puntoReferenciaDestino | string | No | Referencia del lugar de destino. |
ciudad | string | No | Ciudad del servicio. Se completa automáticamente al geocodificar el origen. |
departamento | string | No | Departamento del servicio. Se completa automáticamente al geocodificar el origen. |
fechaCita | string (date) | No | Fecha programada (YYYY-MM-DD). Envía "" para servicio inmediato (se usa la fecha/hora actual). |
horaCita | string | No | Hora programada (HH:MM, 24h). |
observaciones | string | No | Comentarios o instrucciones adicionales. Si envías vehiculo, sus datos se anteponen a este texto. |
vehiculo | object | No | Datos del vehículo (ver tabla abajo). Se envían al técnico junto con la oferta. |
guardian | string | No | "SI" marca la oferta como prioritaria (Servicio Guardián). Por defecto "NO". |
ofertante | string | No | Nombre del ofertante. Por defecto se usa el nombre de negocio de la credencial. |
subOfertante | string | No | Subofertante. Se concatena al ofertante como Ofertante - Subofertante. |
internal | number | No | Identificador de ofertamiento interno. |
global | number | No | Identificador de ofertamiento global. |
socketId | string | No | ID de socket para recibir en tiempo real las respuestas si el UUID ya existía. |
Envía siempre fechaCita
El campo fechaCita se procesa con .trim(). Aunque no programes el servicio, incluye el campo con valor "" (cadena vacía) para agendarlo de forma inmediata.
Objeto vehiculo
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
marca | string | No | Marca del vehículo. |
linea | string | No | Línea del vehículo. |
detalleLinea | string | No | Detalle de la línea. |
modelo | string | No | Modelo o año. |
tipoCombustible | string | No | Tipo de combustible. |
blindaje | string | No | Nivel o indicación de blindaje. |
El objeto vehiculo se incluye solo si al menos uno de sus campos trae datos. Su contenido se formatea como leyenda y se antepone a observaciones.
Ejemplo de Request (por coordenadas)
json
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"latitudOrigen": 6.2442,
"longitudOrigen": -75.5812,
"direccionOrigen": "Carrera 25A #1A Sur-45",
"puntoReferenciaOrigen": "Frente al centro comercial El Tesoro",
"latitudDestino": 6.2518,
"longitudDestino": -75.5636,
"direccionDestino": "Calle 78B #69-240",
"fechaCita": "2025-07-03",
"horaCita": "14:30",
"observaciones": "Vehículo con falla mecánica, requiere grúa especializada",
"descripcionServicio": "Grúa liviana para traslado de automóvil averiado",
"tipoServicio": "1",
"vehiculo": {
"marca": "Toyota",
"linea": "Corolla",
"modelo": "2020",
"tipoCombustible": "Gasolina"
}
}Ejemplo de Request (por dirección, sin coordenadas)
json
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"direccionOrigen": "Carrera 25A #1A Sur-45, Medellín",
"fechaCita": "",
"descripcionServicio": "Grúa liviana para automóvil averiado",
"tipoServicio": "1"
}Respuestas
Éxito (200 Correcto)
json
{
"status": true,
"msg": "SE HA RECIBIDO EXITOSAMENTE LA OFERTA DEL SERVICIO"
}Si el UUID ya se encontraba en proceso de evaluación, la respuesta es igualmente 200 pero con las respuestas registradas hasta el momento:
json
{
"status": true,
"msg": "LA OFERTA YA ESTÁ SIENDO PROCESADA",
"data": {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"offersResponses": []
}
}Error de Validación (400 Solicitud Incorrecta)
Falta el uuid:
json
{
"status": false,
"msg": "NO SE RECIBIÓ EL CAMPO 'uuid', REQUERIDO PARA EJECUTAR LA OFERTA DEL SERVICIO"
}No se envían ni coordenadas ni dirección de origen:
json
{
"status": false,
"msg": "ES NECESARIO LOS DATOS DE LA DIRECCIÓN DE ORIGEN O LAS COORDENADAS DE LA MISMA"
}No se pudo geocodificar la direccionOrigen:
json
{
"status": false,
"msg": "LA DIRECCIÓN DE ORIGEN NO FUE POSIBLE IDENTIFICARLA, POR FAVOR VERIFICA LOS DATOS"
}No se pudo geocodificar la direccionDestino:
json
{
"status": false,
"msg": "LA DIRECCIÓN DE DESTINO NO FUE POSIBLE IDENTIFICARLA, SI NO ES NECESARIO PUEDES OMITIR ESTE CAMPO Y DEJARLO VACÍO"
}Falta el tipoServicio:
json
{
"status": false,
"msg": "EL CAMPO 'tipoServicio' ES REQUERIDO PARA REALIZAR LA OFERTA DEL SERVICIO"
}El UUID ya está ofertado:
json
{
"status": false,
"msg": "EL SERVICIO YA FUE OFERTADO"
}Error de Autenticación (401 / 403)
Las credenciales inválidas o sin permiso al endpoint son gestionadas por el middleware de autenticación. Ver Autenticación.
Webhook de Aceptación
Tras crear la oferta, cuando una central acepta y se selecciona un técnico, TSALVA envía una petición PUT a tu URL de webhook con los datos de la central y del técnico asignado. El detalle del payload, la respuesta esperada y los reintentos se documentan en el webhook de aceptación de oferta.
Ejemplos de Código
cURL
bash
curl -X POST "[URL_API]/api/v3/oferta" \
--user "tu_usuario:tu_password" \
-H "Content-Type: application/json" \
-d '{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"latitudOrigen": 6.2442,
"longitudOrigen": -75.5812,
"direccionOrigen": "Carrera 25A #1A Sur-45",
"fechaCita": "",
"tipoServicio": "1",
"descripcionServicio": "Grúa liviana para automóvil averiado"
}'JavaScript
javascript
const response = await fetch('[URL_API]/api/v3/oferta', {
method: 'POST',
headers: {
'Authorization': `Basic ${btoa('usuario:password')}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
uuid: '123e4567-e89b-12d3-a456-426614174000',
latitudOrigen: 6.2442,
longitudOrigen: -75.5812,
direccionOrigen: 'Carrera 25A #1A Sur-45',
fechaCita: '',
tipoServicio: '1',
descripcionServicio: 'Grúa liviana para automóvil averiado'
})
});
const result = await response.json();
console.log(result);Python
python
import requests
from requests.auth import HTTPBasicAuth
data = {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"latitudOrigen": 6.2442,
"longitudOrigen": -75.5812,
"direccionOrigen": "Carrera 25A #1A Sur-45",
"fechaCita": "",
"tipoServicio": "1",
"descripcionServicio": "Grúa liviana para automóvil averiado"
}
response = requests.post(
'[URL_API]/api/v3/oferta',
auth=HTTPBasicAuth('usuario', 'password'),
json=data
)
result = response.json()
print(result)Notas Importantes
UUID único
- El UUID identifica la oferta. Si ya está ofertado, la petición se rechaza con
"EL SERVICIO YA FUE OFERTADO". - Se recomienda usar UUID v4.
Origen por coordenadas o por dirección
- Puedes enviar el origen por
latitudOrigen+longitudOrigen, o pordireccionOrigen(se geocodifica y se completanciudad/departamento). - Si envías coordenadas en
0o vacías y tampoco envíasdireccionOrigen, la petición falla.
Tipos de Servicio
- Consulta los tipos disponibles en
GET /api/v3/types.
Flujo Siguiente
Después de crear una oferta exitosa:
- Esperar el webhook de aceptación.
- Asignar los detalles del servicio con
POST /api/v3/asignacion. - Si el servicio no se toma, registrar la no asignación; si ya estaba asignado, usar la cancelación.
Consejo
Usa coordenadas precisas para mejor cobertura de centrales. Una ubicación exacta aumenta las posibilidades de que un técnico cercano acepte la oferta.
Importante
Una vez creada la oferta no se puede modificar. Para cambios, retírala con POST /api/v3/no-asignacion y crea una nueva.