Image Processor API
The Image Processor API handles traffic image processing with ANPR (Automatic Number Plate Recognition) integration, violation detection, API health monitoring, and pending events queue management.
Overview
| Procedure | Type | Auth | Description |
|---|---|---|---|
traffic.imageProcessor.processImage | Mutation | No* | Process image with ANPR and route events |
traffic.imageProcessor.getAPIHealth | Query | No | Get ANPR API health status |
traffic.imageProcessor.resetAPIHealth | Mutation | Yes | Reset API health and clear cooloff |
traffic.imageProcessor.getPendingStats | Query | No | Get pending events queue statistics |
traffic.imageProcessor.getPendingEvents | Query | Yes | Get paginated pending events |
traffic.imageProcessor.processPendingEvents | Mutation | Yes | Process pending events manually |
traffic.imageProcessor.retryFailedEvents | Mutation | Yes | Retry all failed events |
traffic.imageProcessor.cancelPendingEvents | Mutation | Yes | Cancel specific pending events |
traffic.imageProcessor.cleanupOldEvents | Mutation | Yes | Delete old processed/failed events |
traffic.imageProcessor.getSpeedThreshold | Query | No | Get speed threshold for location |
traffic.imageProcessor.setLocationSpeedThreshold | Mutation | Yes | Set location speed threshold |
traffic.imageProcessor.getSystemSpeedThreshold | Query | No | Get system default threshold |
traffic.imageProcessor.setSystemSpeedThreshold | Mutation | Yes | Set system default threshold |
traffic.imageProcessor.getViolationStats | Query | Yes | Get violation statistics |
*Requires sensor API key
Event Routing Logic
The image processor routes events to different tables based on detection results:
Image Processing Flow:
│
├─ API Unavailable? → Queue as PendingEvent
│
├─ No vehicle detected → IGNORED (not saved)
│
├─ Speed > threshold → Creates:
│ ├─ SpeedEvent (speed violation record)
│ └─ Event (traffic event with violations)
│
└─ Speed <= threshold → Creates:
└─ Event only (with ANPR violations if any)Violation Types
const VIOLATION_TYPES = {
SEATBELT: "SEATBELT", // Person without seatbelt
HELMET: "HELMET", // Rider without helmet
PHONE_USAGE: "PHONE_USAGE", // Single-hand driving
TRIPLE_RIDE: "TRIPLE_RIDE", // >2 persons on two-wheeler
TAILLIGHT: "TAILLIGHT", // Taillight off
} as const;Vehicle Classes
const VEHICLE_CLASSES = {
CAR: "CAR",
TWO_WHEELER: "TWO_WHEELER",
TRUCK: "TRUCK",
LCV: "LCV",
BUS: "BUS",
AUTO: "AUTO",
} as const;API Health Status
const API_STATUS = {
UP: "UP", // API is operational
DOWN: "DOWN", // API is down (incident created)
DEGRADED: "DEGRADED", // API experiencing issues
} as const;Procedures
traffic.imageProcessor.processImage
Main entry point for processing traffic images with ANPR.
Type: Mutation Auth Required: Sensor API Key (via sensorId)
Input
{
// Image source (one required)
imageBase64?: string;
imageUrl?: string;
// Speed data from radar (optional)
speedKmh?: number;
// Location/Sensor info
sensorId: string;
locationId?: string;
locationName?: string;
// Radar-specific fields (optional)
targetId?: number;
eventType?: number; // Default: 1 (LINE_CROSSING)
laneNumber?: number;
linePosition?: number;
crossingDirection?: number;
lateralPosition?: number;
distance?: number;
captureTimestamp?: number;
// ANPR options
anprOptions?: {
zone_name?: string;
enable_taillight?: boolean;
enable_lp_color?: boolean;
};
// Skip ANPR processing
skipANPR?: boolean;
}Response
{
success: boolean;
routing: "SPEED_EVENT" | "TRAFFIC_EVENT" | "IGNORED";
eventId: string | null;
speedEventId: string | null;
anpr: ProcessedANPRResult | null;
violations: DetectedViolation[];
message: string;
// Queue info (when API unavailable)
queued: boolean;
pendingEventId: string | null;
queuePosition: number | null;
apiStatus: "UP" | "DOWN" | "DEGRADED" | null;
}Example
curl -X POST "https://api.itms.solutions/trpc/traffic.imageProcessor.processImage" \
-H "Content-Type: application/json" \
-d '{
"json": {
"sensorId": "sensor-123",
"imageUrl": "https://storage.example.com/capture.jpg",
"speedKmh": 85,
"locationName": "Main Street Intersection",
"anprOptions": {
"enable_taillight": true,
"enable_lp_color": true
}
}
}'Response Example (Speed Violation)
{
"result": {
"data": {
"json": {
"success": true,
"routing": "SPEED_EVENT",
"eventId": "evt-456",
"speedEventId": "spd-789",
"anpr": {
"success": true,
"licensePlateNumber": "KZ 123 ABC",
"plateConfidence": 0.95,
"vehicleType": "CAR",
"vehicleConfidence": 0.92,
"vehiclesDetected": 1,
"hasViolations": false,
"violations": []
},
"violations": [],
"message": "Speed violation: 85 km/h (limit: 35 km/h). Created SpeedEvent and TrafficEvent.",
"queued": false,
"pendingEventId": null,
"queuePosition": null,
"apiStatus": "UP"
}
}
}
}Response Example (API Unavailable - Queued)
{
"result": {
"data": {
"json": {
"success": true,
"routing": "IGNORED",
"eventId": null,
"speedEventId": null,
"anpr": null,
"violations": [],
"message": "ANPR API unavailable. Event queued for later processing. API in cooloff period. 245s remaining.",
"queued": true,
"pendingEventId": "pnd-123",
"queuePosition": 15,
"apiStatus": "DOWN"
}
}
}
}traffic.imageProcessor.getAPIHealth
Get health status of external APIs (ANPR).
Type: Query Auth Required: No
Input
{
apiName?: string; // Optional: filter by API name
}Response
{
apis: Array<{
id: string;
apiName: string;
status: "UP" | "DOWN" | "DEGRADED";
lastSuccessAt: string | null;
lastFailureAt: string | null;
consecutiveFailures: number;
consecutiveSuccesses: number;
cooloffUntil: string | null;
cooloffRemaining: number | null; // seconds
lastError: string | null;
totalCalls: number;
totalSuccesses: number;
totalFailures: number;
avgResponseTimeMs: number | null;
available: boolean;
reason: string | null;
}>;
}Example
curl "https://api.itms.solutions/trpc/traffic.imageProcessor.getAPIHealth" \
-H "Content-Type: application/json"traffic.imageProcessor.resetAPIHealth
Reset API health status and clear cooloff period.
Type: Mutation Auth Required: Yes
Input
{
apiName: string; // e.g., "ANPR_API"
}Response
{
success: boolean;
message: string;
}traffic.imageProcessor.getPendingStats
Get statistics for the pending events queue.
Type: Query Auth Required: No
Input
{
apiName?: string; // Optional: filter by API
}Response
{
pending: number;
processing: number;
processed: number;
failed: number;
total: number;
oldestPending: string | null; // ISO timestamp
}Example
curl "https://api.itms.solutions/trpc/traffic.imageProcessor.getPendingStats" \
-H "Content-Type: application/json"traffic.imageProcessor.processPendingEvents
Manually trigger processing of pending events.
Type: Mutation Auth Required: Yes
Input
{
limit?: number; // Max events to process (1-100, default: 50)
apiName?: string; // Filter by API
}Response
{
success: boolean;
processed: number;
failed: number;
remaining: number;
message: string;
}Example
curl -X POST "https://api.itms.solutions/trpc/traffic.imageProcessor.processPendingEvents" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
"json": {
"limit": 50
}
}'traffic.imageProcessor.retryFailedEvents
Move all failed events back to pending queue for retry.
Type: Mutation Auth Required: Yes
Input
{
apiName?: string; // Optional: filter by API
}Response
{
success: boolean;
retriedCount: number;
message: string;
}traffic.imageProcessor.getSpeedThreshold
Get the speed threshold for a specific location or sensor.
Type: Query Auth Required: No
Input
{
sensorId?: string;
locationId?: string;
}Response
{
threshold: number; // km/h
default: number; // System default (35 km/h)
}traffic.imageProcessor.setLocationSpeedThreshold
Set the speed threshold for a specific location.
Type: Mutation Auth Required: Yes
Input
{
locationId: string;
threshold: number; // 0-300 km/h
}Response
{
success: boolean;
threshold: number;
}traffic.imageProcessor.getViolationStats
Get violation statistics with filtering.
Type: Query Auth Required: Yes
Input
{
startDate?: string; // ISO timestamp
endDate?: string; // ISO timestamp
sensorId?: string;
locationId?: string;
}Response
{
total: number;
byType: Array<{ violationType: string; count: number }>;
byVehicle: Array<{ vehicleType: string; count: number }>;
dailyTrend: Array<{ date: string; count: number }>;
violationTypes: string[];
}API Health Circuit Breaker
The system implements a circuit breaker pattern for external API calls:
Configuration
| Setting | Default | Description |
|---|---|---|
| Cooloff Duration | 300s (5 min) | Time to wait before retrying |
| Failure Threshold | 3 | Consecutive failures before DOWN |
| Recovery Threshold | 2 | Consecutive successes to recover |
State Transitions
UP ─────────────────────────────────────────────────────────────► UP
│ ▲
│ 1-2 failures │
▼ │
DEGRADED ──────────────────────────────────────────────────────────┤
│ │
│ 3+ failures 2+ consecutive successes │
▼ │
DOWN ──────── cooloff period ends ──────► retry ───────────────────┘Incident Creation
When API status transitions to DOWN:
- An Alert is created with severity CRITICAL
- Incident ID is stored in APIHealthStatus
- When API recovers, incident is automatically resolved
Pending Events Queue
Events are queued when the ANPR API is unavailable:
Event Lifecycle
1. PENDING → Event created, waiting for retry
2. PROCESSING → Currently being processed
3. PROCESSED → Successfully processed, result stored
4. FAILED → Processing failed after max retriesRetry Strategy
- Exponential Backoff: 1min → 2min → 4min → ... (max 1 hour)
- Max Retries: 3 (configurable)
- Priority: Speed violations get higher priority
Cleanup
Use cleanupOldEvents to remove old processed/failed events:
- Default retention: 7 days
- Configurable: 1-365 days
Error Codes
| Code | Description |
|---|---|
INTERNAL_SERVER_ERROR | Database not available |
BAD_REQUEST | Missing required image (base64 or URL) |
NOT_FOUND | Event or resource not found |
UNAUTHORIZED | Invalid or missing authentication |
Related APIs
- Events API - General event management
- Sensors API - Sensor configuration
- System API - System settings