Server-driven config, consent, route and driving event ingestion, plus score and heatmap reports.
GET/api/config
Server-driven config for the driver app
Returns the client's active catalogs (photo sections, vehicle attributes and inspection items) ordered by sort_order. Dual authentication: driver JWT or portal session.
Authentication: Operator JWT
Parameters
tenant query | string Optional | Client slug (defaults to the portal's client) default: cliente del portal |
moment query | string Optional | Filters by moment (applies_to IN (moment, 'both')); omitting returns all receipt | delivery |
curl
curl https://orderafy.app/api/v1/api/config \
-H "Authorization: Bearer JWT_DEL_CHOFER"
Response · Example
{
"tenant": { "id": "1", "name": "Orderafy" },
"moment": null,
"sections": [
{
"id": "1",
"tenantId": "1",
"code": "front",
"title": "Frente (exterior)",
"description": null,
"appliesTo": "both",
"required": true,
"minPhotos": 1,
"maxPhotos": 2,
"sortOrder": 2,
"active": true
}
],
"vehicleFields": [
{
"id": "1",
"tenantId": "1",
"code": "diesel_level",
"label": "Nivel de diésel",
"unit": "%",
"required": true,
"appliesTo": "both",
"sortOrder": 1,
"active": true
}
],
"inspectionItems": [
{
"id": "1",
"tenantId": "1",
"code": "scratches",
"label": "Rayones",
"category": "carrocería",
"states": [{ "value": "minor", "label": "Daño menor" }],
"requiresPhoto": true,
"appliesTo": "both",
"sortOrder": 1,
"active": true
}
]
}
Responses
200Client catalogs
400Invalid moment or disabled client
401Not authenticated (neither driver JWT nor portal session)
404Client not found
GET/api/drivers/{driverId}/telemetria
Telemetry config + driver consent
Consumed by the driver app on open: the config builds the privacy notice and the adaptive GPS interval (server-driven); the consent decides whether tracking may start. consent is null if the driver has not accepted the notice yet.
Authentication: Operator JWT
Parameters
driverId path | integer Required | Driver id (drivers.id); must match the token's driver |
Response · Example
{
"tenant": { "id": "1", "name": "Orderafy" },
"config": {
"tenantId": "1",
"gpsTrackingEnabled": true,
"gpsIntervalSec": 20,
"gpsAdaptive": true,
"driverEventsEnabled": true,
"overspeedLimitKmh": 95,
"appEventsEnabled": true,
"consentRequired": true,
"retentionDays": 90,
"scoreWeights": { "hard_brake": 8, "hard_accel": 6, "sharp_curve": 10, "overspeed": 12 },
"updatedAt": "2026-08-31T09:00:00-06:00"
},
"consent": {
"id": "3",
"driverId": "2",
"version": "v2",
"gpsOk": true,
"behaviorOk": true,
"analyticsOk": false,
"acceptedAt": "2026-08-28T11:20:00-06:00"
},
"noticeVersion": "v2",
"fetchedAt": "2026-08-31T09:12:00-06:00"
}
Responses
200Config + consent
401No valid JWT
403The token does not match the route's driver
503Database unavailable
POST/api/drivers/{driverId}/consent
Record/update driver consent
Upsert by (driver_id, version). Turning a flag off is revocation: the server rejects ingestion for the revoked scope.
Authentication: Operator JWT
Parameters
driverId path | integer Required | Driver id |
Request · Example
{
"version": "v2",
"gps": true,
"behavior": true,
"analytics": false,
"deviceId": "6f0c2f7e-4a5b-4f5e-9a1c-9b0f4b1f2f10"
}
Responses
200Consent recorded/updated
400Invalid payload
401No valid JWT
403The token does not match the route's driver
404Driver does not exist
POST/api/drivers/{driverId}/tracks
Track points ingestion (batch)
Idempotent via UNIQUE (order_id, device_ts): retrying the same batch (same batchId) does not duplicate points. Validations: every order in the batch belongs to the driver and is in transit; consent must be current; lat/lng in range; deviceTs no more than 5 min in the future. The whole batch is rejected if consent was revoked or telemetry is disabled.
Authentication: Operator JWT
Parameters
driverId path | integer Required | Driver id |
Request · Example
{
"batchId": "3f2a1c4e-9b7d-4e5a-8f0c-1d2e3f4a5b6c",
"points": [
{
"orderId": 42,
"lat": 25.7894,
"lng": -100.2653,
"speedKmh": 62,
"heading": 214,
"accuracyM": 4.2,
"source": "gps",
"deviceTs": "2026-08-31T14:05:10-06:00"
}
]
}
Response · Example
{
"accepted": 30,
"duplicates": 0
}
Responses
202Batch accepted (accepted + duplicates)
400Invalid payload or point (order not in transit, coordinates out of range, future deviceTs…)
401No valid JWT
403Another driver's token, telemetry disabled or consent revoked
503Database unavailable
POST/api/drivers/{driverId}/events
Driving events ingestion (batch)
Driving behavior events detected by the driver app (hard brakes, accelerations, sharp curves, overspeed). Idempotent via UNIQUE (order_id, device_ts, type). Same validations as tracks: order in transit, current consent and type within the enum.
Authentication: Operator JWT
Parameters
driverId path | integer Required | Driver id |
Request · Example
{
"batchId": "3f2a1c4e-9b7d-4e5a-8f0c-1d2e3f4a5b6c",
"events": [
{
"orderId": 42,
"type": "hard_brake",
"lat": 25.7894,
"lng": -100.2653,
"magnitude": 0.62,
"deviceTs": "2026-08-31T14:22:41-06:00"
}
]
}
Response · Example
{
"accepted": 30,
"duplicates": 0
}
Responses
202Batch accepted (accepted + duplicates)
400Invalid payload or event (order not in transit, type outside enum, future deviceTs…)
401No valid JWT
403Another driver's token, events disabled or behavior consent revoked
503Database unavailable
GET/api/ordenes/{id}/recorrido
Order route (polyline + statistics)
Route map: points ordered by device_ts, real distance (Haversine sum), duration, stop zones (speed < 5 km/h for > 2 min) and estimated origin→destination distance. Admin/monitoring role (admin|staff|dealer; dealers only see their own orders).
Authentication: Portal session
Parameters
id path | integer Required | Order id |
Response · Example
{
"orden": {
"id": "42",
"orderNumber": "INT-2026-0831-001",
"status": "in_transit",
"origin": "Planta Escobedo, Nuevo León",
"destination": "Distribuidor International Monterrey, NL",
"dealerName": "International Monterrey",
"unitVin": "3HCDZAPR9SL123456",
"unitDescription": "Camión International HV 2026",
"driverId": "2",
"driverName": "Carlos Ramírez"
},
"points": [
{
"lat": 25.7894,
"lng": -100.2653,
"speedKmh": 62,
"heading": 214,
"accuracyM": 4.2,
"source": "gps",
"deviceTs": "2026-08-31T14:05:10-06:00"
}
],
"stats": {
"points": 182,
"distanceKm": 48.3,
"durationSec": 5220,
"startTs": "2026-08-31T12:40:00-06:00",
"endTs": "2026-08-31T14:07:00-06:00",
"stops": [
{
"lat": 25.7911,
"lng": -100.2584,
"startTs": "2026-08-31T13:15:00-06:00",
"endTs": "2026-08-31T13:22:00-06:00",
"durationSec": 420,
"avgSpeedKmh": 0
}
],
"estimatedDistanceKm": null
}
}
Responses
200Order route
400Invalid id
401No portal session
404Order not found or outside the dealer's scope
503Database unavailable
GET/api/ordenes/{id}/eventos
Order driving events (with acknowledged status)
Lists an order's driving behavior events (hard brakes, accelerations, sharp curves, overspeed) with their acknowledged status for monitoring. Ordered by device_ts descending. Admin/monitoring role.
Authentication: Portal session
Parameters
id path | integer Required | Order id |
Response · Example
{
"orderId": 42,
"orderNumber": "INT-2026-0831-001",
"events": [
{
"id": "128",
"orderId": 42,
"driverId": 2,
"driverName": "Carlos Ramírez",
"type": "hard_brake",
"lat": 25.7894,
"lng": -100.2653,
"magnitude": 0.62,
"deviceTs": "2026-08-31T14:22:41-06:00",
"receivedAt": "2026-08-31T14:22:42-06:00",
"acknowledged": true
}
],
"total": 1
}
Responses
200Order events
400Invalid id
401No portal session
404Order not found or outside the dealer's scope
503Database unavailable
POST/api/ordenes/{id}/eventos/{eventId}/ack
Acknowledge or dismiss a driving event
Monitoring acknowledges (acknowledged: true) or dismisses (false) an order's driving event. Admin/monitoring role (dealers only on their own orders).
Authentication: Portal session
Parameters
id path | integer Required | Order id |
eventId path | integer Required | Driving event id |
Response · Example
{
"id": "128",
"orderId": 42,
"driverId": 2,
"driverName": "Carlos Ramírez",
"type": "hard_brake",
"lat": 25.7894,
"lng": -100.2653,
"magnitude": 0.62,
"deviceTs": "2026-08-31T14:22:41-06:00",
"receivedAt": "2026-08-31T14:22:42-06:00",
"acknowledged": true
}
Responses
200Event updated
400Invalid id or body
401No portal session
404Order or event not found
503Database unavailable
GET/api/reports/telemetria/score
Driving score 0–100 + weekly trend + driving mode
Driving score (Geotab pattern): max(0, 100 − Σ(weight × N/km) × 100), normalized per 100 km using real km from order_tracks. Weights from score_weights (defaults: hard_brake 8, hard_accel 6, sharp_curve 10, overspeed 12). Score is null if km < 50 in the period (not enough data). Without driverId it returns the fleet aggregate; per-driver breakdown requires the admin role.
Authentication: Portal session
Parameters
driverId query | integer Optional | Per-driver breakdown (requires admin role) |
from query | string Optional | Period start (ISO 8601) |
to query | string Optional | Period end (ISO 8601); defaults to now |
Response · Example
{
"driverId": null,
"from": "2026-06-01T00:00:00-06:00",
"to": "2026-08-31T23:59:59-06:00",
"km": 4820.5,
"events": { "hard_brake": 3, "hard_accel": 1, "sharp_curve": 0, "overspeed": 0 },
"weights": { "hard_brake": 8, "hard_accel": 6, "sharp_curve": 10, "overspeed": 12 },
"score": 92,
"trend": [
{ "weekStart": "2026-08-03", "km": 610.2, "events": { "hard_brake": 1, "hard_accel": 0, "sharp_curve": 0, "overspeed": 0 }, "score": 97 },
{ "weekStart": "2026-08-10", "km": 655.8, "events": { "hard_brake": 2, "hard_accel": 1, "sharp_curve": 0, "overspeed": 0 }, "score": 94 }
],
"drivingModes": {
"urbano": { "segments": 24, "km": 320.1 },
"mixto": { "segments": 18, "km": 890.4 },
"carretera": { "segments": 9, "km": 3610.0 }
}
}
Responses
200Score, trend and driving modes
400Invalid parameters
401No portal session
403Per-driver breakdown without admin role
503Database unavailable
GET/api/reports/telemetria/heatmap
Route activity heatmap
Points aggregated by ~4-decimal cell (≈ 11 m). Aggregated by default (privacy); the per-driver filter (breakdown) requires the admin role. Without from, the default period is the last 90 days (retention).
Authentication: Portal session
Parameters
driverId query | integer Optional | Per-driver breakdown (requires admin role) |
from query | string Optional | Period start (ISO 8601) |
to query | string Optional | Period end (ISO 8601); defaults to now |
Response · Example
{
"points": [
{ "lat": 25.7894, "lng": -100.2653, "count": 12, "intensity": 0.8 }
],
"total": 240,
"from": "2026-06-01T00:00:00-06:00",
"to": "2026-08-31T23:59:59-06:00",
"driverId": null
}
Responses
200Aggregated cells
400Invalid parameters
401No portal session
403Per-driver breakdown without admin role
503Database unavailable