Tracking Service API Documentation
Base URL
/api/tracking (internal root path)
Routes are exposed at:
/api/positions- Position data/api/events- Event data/api/geofences- Geofence management
📘 TypeScript Interfaces
Use these interfaces for your frontend integration.
// Position Object
export interface Position {
id: number;
deviceId: number;
protocol: string | null;
serverTime: string | null; // ISO 8601
deviceTime: string | null; // ISO 8601
fixTime: string | null; // ISO 8601
valid: boolean;
latitude: number;
longitude: number;
altitude: number;
speed: number; // knots
course: number; // degrees
accuracy: number;
address: string | null;
attributes: Record<string, any>;
}
// Event Object
export interface Event {
id: number;
type: string;
eventTime: string | null; // ISO 8601
deviceId: number;
positionId: number | null;
geofenceId: number | null;
maintenanceId: number | null;
attributes: Record<string, any>;
}
// Event Types
export type EventType =
| 'deviceOnline'
| 'deviceOffline'
| 'deviceUnknown'
| 'deviceInactive'
| 'deviceMoving'
| 'deviceStopped'
| 'deviceOverspeed'
| 'deviceFuelDrop'
| 'deviceFuelIncrease'
| 'geofenceEnter'
| 'geofenceExit'
| 'alarm'
| 'ignitionOn'
| 'ignitionOff'
| 'maintenance'
| 'textMessage'
| 'driverChanged'
| 'commandResult';
// Geofence Object
export interface Geofence {
id: number;
name: string;
description: string | null;
area: string; // WKT format
calendarId: number | null;
attributes: Record<string, any>;
}
// Geofence Create Request
export interface GeofenceCreateRequest {
name: string;
description?: string;
area: string; // WKT: CIRCLE, POLYGON, or LINESTRING
calendarId?: number;
attributes?: Record<string, any>;
}
// Geofence Update Request
export interface GeofenceUpdateRequest {
name?: string;
description?: string;
area?: string;
calendarId?: number;
attributes?: Record<string, any>;
}
// Health Check Response
export interface HealthResponse {
status: 'healthy' | 'degraded';
service: string;
ready: boolean;
database: 'connected' | 'disconnected';
}
🛠️ Frontend Integration Guide
1. Authentication
All tracking endpoints require authentication.
The gateway validates JWT tokens and passes X-User-Id header to the service.
Frontend Requirement:
You MUST include the JWT token in the Authorization header for all authenticated requests.
await fetch('/api/positions/', {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
2. Speed Units
Speed values are stored in knots. Convert for display:
- 1 knot = 1.852 km/h
- 1 knot = 1.151 mph
3. Error Handling
| Status | Meaning | Action |
|---|---|---|
| 401 Unauthorized | Not logged in | Redirect to login |
| 403 Forbidden | Access denied to device/geofence | Show access error |
| 404 Not Found | Resource not found | Show not found error |
| 400 Bad Request | Invalid request data | Show validation error |
📡 Endpoints
1. Positions
Get Positions
GET /api/positions/
- Auth Required: Yes
- Query Params:
deviceId: Filter by device IDid: Get specific position IDs (can repeat)from: Start time (ISO 8601) - required withtofor historyto: End time (ISO 8601) - required withfromfor history
- Response:
Position[]
Get latest position for device:
GET /api/positions/?deviceId=123
Get position history:
GET /api/positions/?deviceId=123&from=2024-12-01T00:00:00Z&to=2024-12-08T00:00:00Z
Get latest positions for all user's devices:
GET /api/positions/
Delete Positions
DELETE /api/positions/
- Auth Required: Yes
- Permission: Owner only (shared users cannot delete history)
- Query Params (all required):
deviceId: Device IDfrom: Start time (ISO 8601)to: End time (ISO 8601)
- Response: 204 No Content
- Errors:
- 403 Forbidden: User doesn't own this device or lacks permission
2. Events
List Events
GET /api/events/
- Auth Required: Yes
- Query Params:
deviceId: Filter by device ID (optional)from: Start time (ISO 8601)to: End time (ISO 8601)type: Filter by event type
- Response:
Event[](max 1000)
Get events for device:
GET /api/events/?deviceId=123&from=2024-12-01T00:00:00Z&to=2024-12-08T00:00:00Z
Get overspeed events:
GET /api/events/?type=deviceOverspeed
Get Event
GET /api/events/{id}
- Auth Required: Yes
- Response:
Event - Errors:
- 403 Forbidden: User doesn't own the device that generated this event
- 404 Not Found: Event doesn't exist
3. Geofences
List Geofences
GET /api/geofences/
- Auth Required: Yes
- Query Params:
userId: Filter by user (optional)all: Get all accessible geofences (optional)
- Response:
Geofence[]
Create Geofence
POST /api/geofences/
- Auth Required: Yes
- Content-Type:
application/json - Body:
GeofenceCreateRequest
Circle Example:
{
"name": "Office",
"description": "Main office building",
"area": "CIRCLE (45.4654 9.1859, 100)"
}
Format:
CIRCLE (latitude longitude, radius_in_meters)
Polygon Example:
{
"name": "Warehouse Zone",
"description": "Warehouse perimeter",
"area": "POLYGON ((45.4654 9.1859, 45.4655 9.1860, 45.4656 9.1858, 45.4654 9.1859))"
}
Format:
POLYGON ((lat1 lon1, lat2 lon2, ..., lat1 lon1))- must close the polygon
- Response: 201 Created
Geofence - Errors:
- 400 Bad Request: Invalid area format
Get Geofence
GET /api/geofences/{id}
- Auth Required: Yes
- Response:
Geofence - Errors:
- 403 Forbidden: User doesn't own this geofence
- 404 Not Found: Geofence doesn't exist
Update Geofence
PUT /api/geofences/{id}
- Auth Required: Yes
- Content-Type:
application/json - Body:
GeofenceUpdateRequest
{
"name": "Updated Name",
"description": "Updated description"
}
- Response:
Geofence - Errors:
- 400 Bad Request: Invalid area format
- 403 Forbidden: User doesn't own this geofence
- 404 Not Found: Geofence doesn't exist
Delete Geofence
DELETE /api/geofences/{id}
- Auth Required: Yes
- Response: 204 No Content
- Errors:
- 403 Forbidden: User doesn't own this geofence
- 404 Not Found: Geofence doesn't exist
4. Health
Health Check (Public)
GET /api/tracking/health
- Auth Required: No
- Response:
{
"status": "healthy",
"service": "tracking-service",
"ready": true,
"database": "connected"
}