Skip to main content

Device Service API Documentation

Base URL

/api/devices

📘 TypeScript Interfaces

Use these interfaces for your frontend integration.

// Device Object
export interface Device {
id: number;
name: string;
uniqueId: string;
status: 'online' | 'offline' | 'unknown';
lastUpdate: string | null; // ISO 8601
positionId: number | null;
phone: string | null;
model: string | null;
contact: string | null;
category: string | null;
disabled: boolean;
expirationTime: string | null;
groupId: number | null;
calendarId: number | null;
attributes: Record<string, any>;
claimToken?: string; // Only for claimed devices (owner only)
// Sharing/Permissions
isOwner: boolean;
permissions: DevicePermissions;
sharedBy?: number; // User ID who shared (only for non-owners)
}

// Device Permissions
export interface DevicePermissions {
position: boolean; // View positions and history
events: boolean; // View device events
geofences: boolean; // View geofences
notifications: boolean; // Receive notifications
commands: boolean; // Send commands to device
}

// Device Create Request
export interface DeviceCreateRequest {
name: string;
uniqueId: string;
phone?: string;
model?: string;
contact?: string;
category?: string;
groupId?: number;
attributes?: Record<string, any>;
deviceToken?: string; // Optional: claim token to mark as claimed
}

// Device Update Request
export interface DeviceUpdateRequest {
name?: string;
phone?: string;
model?: string;
contact?: string;
category?: string;
groupId?: number;
disabled?: boolean;
attributes?: Record<string, any>;
}

// Token Validation Request
export interface TokenValidateRequest {
token: string;
}

// Token Validation Response (Success)
export interface TokenValidateSuccess {
success: true;
uniqueId: string;
model: string;
modelCode: string;
}

// Token Validation Response (Error)
export interface TokenValidateError {
success: false;
errorCode: 'TOKEN_REQUIRED' | 'TOKEN_INVALID' | 'TOKEN_ALREADY_CLAIMED';
errorMessage: string;
}

export type TokenValidateResponse = TokenValidateSuccess | TokenValidateError;

// Device Claim Request
export interface DeviceClaimRequest {
token: string;
}

// Device Claim Response
export interface DeviceClaimResponse {
success: boolean;
device?: Device;
alreadyClaimed?: boolean;
}

// Health Check Response
export interface HealthResponse {
status: 'healthy' | 'degraded';
service: string;
ready: boolean;
database: 'connected' | 'disconnected';
}

🛠️ Frontend Integration Guide

1. Authentication

All device endpoints (except health and validate-token) 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/devices', {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

2. Device Claiming Flow

  1. User enters claim token (from device packaging/QR code)
  2. Call POST /api/devices/validate-token to verify token and preview device
  3. If valid, call POST /api/devices/claim to claim the device
  4. Device is now linked to user account

3. Error Handling

StatusMeaningAction
401 UnauthorizedNot logged inRedirect to login
403 ForbiddenAccess denied to deviceShow access error
404 Not FoundDevice/token not foundShow not found error
409 ConflictDevice already exists or claimedShow conflict message

📡 Endpoints

1. Device CRUD

List Devices

GET /

  • Auth Required: Yes
  • Query Params:
    • userId: Filter by user (optional)
    • uniqueId: Filter by unique IDs (optional, can repeat)
    • id: Filter by device IDs (optional, can repeat)
  • Response: Device[]
[
{
"id": 1,
"name": "My Car Tracker",
"uniqueId": "123456789012345",
"status": "online",
"lastUpdate": "2024-12-08T12:30:00Z",
"model": "S21L",
"disabled": false,
"attributes": {}
}
]

Get Device

GET /{id}

  • Auth Required: Yes
  • Response: Device
  • Errors:
    • 403 Forbidden: User doesn't own this device
    • 404 Not Found: Device doesn't exist

Create Device

POST /

  • Auth Required: Yes
  • Content-Type: application/json
  • Body: DeviceCreateRequest
{
"name": "My GPS Tracker",
"uniqueId": "123456789012345",
"phone": "+39123456789",
"model": "S21L",
"category": "car"
}
  • Response: 201 Created Device
  • Errors:
    • 409 Conflict: Device with this uniqueId already exists

Update Device

PUT /{id}

  • Auth Required: Yes
  • Content-Type: application/json
  • Body: DeviceUpdateRequest
{
"name": "Updated Name",
"phone": "+39987654321",
"disabled": false
}
  • Response: Device
  • Errors:
    • 403 Forbidden: User doesn't own this device
    • 404 Not Found: Device doesn't exist

Delete Device

DELETE /{id}

  • Auth Required: Yes
  • Response: 204 No Content
  • Errors:
    • 403 Forbidden: User doesn't own this device
    • 404 Not Found: Device doesn't exist

2. Token Validation & Claiming

Validate Token (Public)

POST /validate-token

  • Auth Required: No
  • Purpose: Check if a claim token is valid and preview device info before claiming
  • Content-Type: application/json
  • Body: TokenValidateRequest
{
"token": "CLAIM_TOKEN_HERE"
}
  • Response (Success):
{
"success": true,
"uniqueId": "123456789012345",
"model": "Visla S21L",
"modelCode": "S21L"
}
  • Response (Error):
{
"success": false,
"errorCode": "TOKEN_ALREADY_CLAIMED",
"errorMessage": "Device already claimed"
}
  • Error Codes:
    • TOKEN_REQUIRED: No token provided
    • TOKEN_INVALID: Token not found or invalid status
    • TOKEN_ALREADY_CLAIMED: Device already claimed by another user

Claim Device

POST /claim

  • Auth Required: Yes
  • Purpose: Claim a device using a token (creates device if needed, links to user)
  • Content-Type: application/json
  • Body: DeviceClaimRequest
{
"token": "CLAIM_TOKEN_HERE"
}
  • Response (Success):
{
"success": true,
"device": {
"id": 1,
"name": "Visla S21L",
"uniqueId": "123456789012345",
"status": "offline",
"model": "S21L"
}
}
  • Response (Already Claimed by Same User):
{
"success": true,
"device": { ... },
"alreadyClaimed": true
}
  • Errors:
    • 400 Bad Request: Token missing or device not configured
    • 404 Not Found: Token doesn't exist
    • 409 Conflict: Token already used by another user

3. Health

Health Check (Public)

GET /health

  • Auth Required: No
  • Response:
{
"status": "healthy",
"service": "device-service",
"ready": true,
"database": "connected"
}