La API REST de SIGA proporciona endpoints para gestionar decisiones de flota, predicciones, optimizaci贸n y tracking en tiempo real. Toda la API est谩 documentada en OpenAPI 3.0 y accesible v铆a Swagger UI.
Todos los endpoints requieren autenticaci贸n JWT Bearer token:
Authorization: Bearer <token>
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "dispatcher01",
"password": "secure_password"
}
Respuesta:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": 1,
"username": "dispatcher01",
"role": "dispatcher",
"permissions": ["view_fleet", "create_decisions", "view_analytics"]
}
}
POST /api/v1/decisions/evaluate
Content-Type: application/json
{
"vehicle_id": 12,
"current_position": {
"lat": 40.416775,
"lng": -3.703790
},
"available_loads": [
{
"id": "LOAD-001",
"origin": "Madrid",
"destination": "Barcelona",
"revenue": 850.00,
"pickup_time": "2025-07-23T10:00:00Z",
"weight_kg": 18000
}
],
"evaluation_horizon_hours": 48
}
Respuesta:
{
"evaluation_id": "eval_20250722_120034",
"recommendations": [
{
"rank": 1,
"action": "accept_load",
"load_id": "LOAD-001",
"expected_value": 742.50,
"confidence": 0.85,
"justification": {
"revenue": 850.00,
"empty_km_cost": -107.50,
"future_position_value": 234.00,
"total_score": 976.50
},
"predicted_outcomes": {
"empty_km": 143,
"revenue_per_km": 4.32,
"next_load_probability": 0.78
}
},
{
"rank": 2,
"action": "reposition",
"target_zone": "Valencia",
"expected_value": 456.00,
"confidence": 0.72
}
],
"analysis_time_ms": 234
}
POST /api/v1/decisions/record
Content-Type: application/json
{
"evaluation_id": "eval_20250722_120034",
"decision_taken": {
"action": "accept_load",
"load_id": "LOAD-001",
"timestamp": "2025-07-22T12:01:00Z",
"dispatcher_id": "USR001",
"override_reason": null
}
}
GET /api/v1/fleet/status
Query Parameters:
zone (optional): Filtrar por zona geogr谩ficastatus (optional): available, in_transit, loading, unloadinginclude_predictions (optional): Incluir predicciones de disponibilidadRespuesta:
{
"fleet_summary": {
"total_vehicles": 42,
"available_now": 8,
"in_transit": 28,
"loading_unloading": 6,
"maintenance": 0
},
"vehicles": [
{
"id": 12,
"plate": "1234-ABC",
"current_position": {
"lat": 40.416775,
"lng": -3.703790,
"zone": "Madrid-Centro"
},
"status": "available",
"capacity_kg": 24000,
"next_available": "2025-07-22T14:30:00Z",
"driver": {
"id": "DRV-045",
"name": "Juan P茅rez",
"hours_driven_today": 5.5
}
}
],
"zone_distribution": {
"Madrid": 12,
"Barcelona": 8,
"Valencia": 6,
"Sevilla": 4
}
}
GET /api/v1/fleet/tracking/{vehicle_id}
Respuesta con Server-Sent Events (SSE):
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
event: position_update
data: {"lat": 40.416775, "lng": -3.703790, "speed_kmh": 85, "heading": 45, "timestamp": "2025-07-22T12:05:00Z"}
event: status_change
data: {"status": "loading", "location": "LIDL Distribution Center Madrid", "estimated_duration": 45}
GET /api/v1/predictions/demand/{zone}
Query Parameters:
horizon_hours (default: 48): Horizonte de predicci贸ngranularity (default: "hourly"): hourly, daily, weeklyRespuesta:
{
"zone": "Madrid",
"predictions": [
{
"timestamp": "2025-07-23T00:00:00Z",
"demand_level": "high",
"probability": 0.82,
"expected_loads": 12,
"avg_revenue_per_load": 750.00,
"confidence_interval": {
"lower": 8,
"upper": 16
}
}
],
"historical_accuracy": 0.78,
"factors": {
"day_of_week": 0.25,
"time_of_day": 0.20,
"seasonal": 0.15,
"events": 0.10
}
}
GET /api/v1/predictions/heatmap
Query Parameters:
timestamp: Momento espec铆fico para predicci贸nresolution: province, city, postal_codeRespuesta:
{
"timestamp": "2025-07-23T12:00:00Z",
"heatmap": [
{
"zone_id": "MAD",
"zone_name": "Madrid",
"center": {"lat": 40.416775, "lng": -3.703790},
"demand_score": 0.85,
"supply_score": 0.45,
"imbalance_score": 0.40,
"recommended_vehicles": 8,
"color_hex": "#FF5733"
}
],
"legend": {
"demand_score": "0-1 scale of expected demand",
"supply_score": "0-1 scale of vehicle availability",
"imbalance_score": "abs(demand - supply), higher means more imbalance"
}
}
POST /api/v1/optimization/multi-day
Content-Type: application/json
{
"horizon_days": 3,
"vehicles": [12, 13, 14, 15],
"constraints": {
"max_driving_hours_per_day": 9,
"mandatory_rest_hours": 11,
"max_km_per_day": 800,
"home_base_return": true
},
"objectives": {
"minimize_empty_km": 0.4,
"maximize_revenue": 0.3,
"balance_fleet_distribution": 0.3
},
"known_loads": [
{
"id": "LOAD-001",
"pickup_time": "2025-07-23T10:00:00Z",
"origin": "Madrid",
"destination": "Barcelona"
}
]
}
Respuesta:
{
"optimization_id": "opt_20250722_130000",
"status": "completed",
"solution_quality": 0.92,
"execution_time_ms": 1234,
"plan": {
"total_revenue": 28500.00,
"total_empty_km": 580,
"vehicle_plans": [
{
"vehicle_id": 12,
"schedule": [
{
"day": 1,
"activities": [
{
"type": "load",
"load_id": "LOAD-001",
"start_time": "2025-07-23T10:00:00Z",
"end_time": "2025-07-23T16:00:00Z",
"revenue": 850.00
},
{
"type": "reposition",
"from": "Barcelona",
"to": "Valencia",
"empty_km": 350,
"justification": "High demand probability in Valencia for day 2"
}
]
}
]
}
]
},
"alternatives": [
{
"description": "Conservative plan - minimize repositioning",
"total_revenue": 26800.00,
"total_empty_km": 420
}
]
}
GET /api/v1/analytics/kpis
Query Parameters:
period: today, week, month, quarter, yearcompare_to: previous_period, same_period_last_yearRespuesta:
{
"period": {
"start": "2025-07-01T00:00:00Z",
"end": "2025-07-22T23:59:59Z"
},
"kpis": {
"empty_km_ratio": {
"value": 0.285,
"change": -0.032,
"trend": "improving",
"target": 0.250
},
"revenue_per_km": {
"value": 2.84,
"currency": "EUR",
"change": 0.12,
"trend": "improving"
},
"vehicle_utilization": {
"value": 0.78,
"change": 0.05,
"breakdown": {
"driving": 0.45,
"loading_unloading": 0.15,
"rest": 0.33,
"idle": 0.07
}
},
"decision_accuracy": {
"value": 0.82,
"total_decisions": 1234,
"optimal_decisions": 1012
}
},
"insights": [
{
"type": "opportunity",
"message": "Valencia zone shows 23% undersupply on Tuesdays",
"impact": "Could reduce empty km by ~150km/week",
"action": "Consider permanent vehicle allocation"
}
]
}
GET /api/v1/analytics/flows
Query Parameters:
origin_zone: Filtrar por zona de origendestination_zone: Filtrar por zona de destinomin_frequency: N煤mero m铆nimo de viajesRespuesta:
{
"flow_analysis": {
"period": "last_30_days",
"total_flows": 156,
"top_flows": [
{
"origin": "Madrid",
"destination": "Barcelona",
"frequency": 45,
"avg_revenue": 850.00,
"avg_empty_return_km": 280,
"balance_score": -0.65,
"recommendation": "Seek return loads BCN->MAD"
}
],
"imbalanced_zones": [
{
"zone": "Sevilla",
"net_flow": -23,
"type": "sink",
"monthly_repositioning_cost": 3450.00
}
]
},
"sankey_data": {
"nodes": [
{"id": 0, "name": "Madrid"},
{"id": 1, "name": "Barcelona"}
],
"links": [
{"source": 0, "target": 1, "value": 45}
]
}
}
POST /api/v1/integrations/rtracktor/sync
Content-Type: application/json
{
"sync_type": "full",
"include": ["vehicles", "loads", "routes"],
"since": "2025-07-22T00:00:00Z"
}
Respuesta:
{
"sync_id": "sync_20250722_140000",
"status": "in_progress",
"progress": {
"vehicles": {
"total": 42,
"synced": 42,
"errors": 0
},
"loads": {
"total": 156,
"synced": 120,
"errors": 2
}
},
"estimated_completion": "2025-07-22T14:05:00Z"
}
SIGA puede enviar webhooks para eventos importantes:
POST /api/v1/webhooks
Content-Type: application/json
{
"url": "https://your-system.com/webhook",
"events": ["decision.created", "vehicle.status_changed", "alert.triggered"],
"secret": "your_webhook_secret"
}
decision.created: Nueva decisi贸n registradadecision.executed: Decisi贸n ejecutadavehicle.status_changed: Cambio de estado de veh铆culoalert.triggered: Alerta del sistema (desbalance, etc.)prediction.updated: Actualizaci贸n de prediccionesoptimization.completed: Optimizaci贸n finalizada{
"event": "alert.triggered",
"timestamp": "2025-07-22T14:00:00Z",
"data": {
"alert_type": "zone_imbalance",
"zone": "Valencia",
"severity": "high",
"message": "Valencia zone has 8 vehicles but needs 12 for expected demand",
"recommended_action": "Reposition 4 vehicles from Barcelona"
},
"signature": "sha256=abcdef..."
}
Los l铆mites de rate var铆an seg煤n el tipo de endpoint:
| Endpoint Type | L铆mite | Ventana |
|---|---|---|
| Auth | 10 | 1 minuto |
| Decisions | 100 | 1 minuto |
| Analytics | 50 | 1 minuto |
| Predictions | 200 | 1 minuto |
| Tracking | 1000 | 1 minuto |
Headers de respuesta:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1627058400
La API usa c贸digos de estado HTTP est谩ndar y devuelve errores en formato JSON:
{
"error": {
"code": "VEHICLE_NOT_FOUND",
"message": "Vehicle with ID 999 not found",
"details": {
"vehicle_id": 999,
"suggestion": "Check vehicle ID or sync with Rtracktor"
},
"request_id": "req_abc123",
"timestamp": "2025-07-22T14:00:00Z"
}
}
400: Bad Request - Par谩metros inv谩lidos401: Unauthorized - Token inv谩lido o expirado403: Forbidden - Sin permisos para la operaci贸n404: Not Found - Recurso no encontrado409: Conflict - Conflicto con estado actual422: Unprocessable Entity - Datos v谩lidos pero no procesables429: Too Many Requests - Rate limit excedido500: Internal Server Error - Error del servidor503: Service Unavailable - Servicio temporalmente no disponibleAmbiente de staging disponible en:
https://api-staging.siga.example.com
Credenciales de test:
test_dispatchertest_password_123Datos de prueba se resetean diariamente a las 00:00 UTC.
猬咃笍 Volver a Documentaci贸n T茅cnica | 鉃★笍 Siguiente: Modelos ML