Files
boc/vims-backend/docs/API.md
T
Bernt 6de2455917 v1.2.0: Add Global Markets footer, translated to 9 languages
- Added GLOBAL_MARKETS_TITLE to all translation files
- Updated footer with 12 markets (4 active + 8 upcoming)
- Translated market section to: zh-cn, zh-tw, ja, ko, th, vi, id, ms, hi
- Built and deployed to production
- CloudFront invalidation: I3RTMXVFDJXWLG3SYX208OP1CC
2026-07-08 19:56:03 +00:00

367 lines
6.1 KiB
Markdown

# VIMS API Documentation
## Base URL
```
Production: https://vims.landvex.com/api/v1
Development: http://localhost:3450/api/v1
```
## Authentication
All endpoints require Bearer token authentication:
```
Authorization: Bearer <token>
```
## Endpoints
### Objects
#### List Objects
```http
GET /api/v1/objects
```
Query Parameters:
- `type` - Filter by object type (atm, charging_station, parking_meter, defibrillator)
- `status` - Filter by status (green, yellow, orange, red, unknown)
- `customerId` - Filter by customer
- `page` - Page number (default: 1)
- `limit` - Items per page (default: 20)
- `search` - Search in name, externalId, address
Response:
```json
{
"objects": [
{
"id": "uuid",
"name": "ATM Sveavägen 123",
"objectType": {
"name": "Bankomat",
"category": "payment"
},
"currentStatus": "green",
"location": {
"latitude": 59.3368,
"longitude": 18.0555
},
"lastInspection": "2026-07-08T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"pages": 5
}
}
```
#### Create Object
```http
POST /api/v1/objects
```
Request Body:
```json
{
"objectTypeId": "uuid",
"customerId": "uuid",
"name": "ATM Sveavägen 123",
"externalId": "ATM-001",
"location": {
"latitude": 59.3368,
"longitude": 18.0555
},
"address": "Sveavägen 123, Stockholm",
"manufacturer": "NCR",
"model": "SelfServ 22",
"installationDate": "2025-01-15"
}
```
#### Set Baseline Images
```http
POST /api/v1/objects/:id/baseline
```
Request Body:
```json
{
"images": [
{
"angle": "front",
"imageUrl": "https://s3.landvex.com/baseline/atm-001-front.jpg"
},
{
"angle": "back",
"imageUrl": "https://s3.landvex.com/baseline/atm-001-back.jpg"
}
]
}
```
### Observations
#### Upload Observation
```http
POST /api/v1/observations
```
Content-Type: `multipart/form-data`
Fields:
- `images` - Image files (JPEG, PNG, WebP)
- `objectId` - Object UUID
- `angle` - Camera angle (front, back, left, right, top, detail)
- `zoomerId` - Zoomer UUID (optional)
- `missionId` - Mission UUID (optional)
- `takenAt` - ISO timestamp (optional)
- `gpsAccuracy` - GPS accuracy in meters (optional)
Response:
```json
{
"observations": [
{
"id": "uuid",
"status": "pending",
"imageUrl": "https://s3.landvex.com/obs/..."
}
],
"objectId": "uuid",
"processed": 1
}
```
#### Get Observation
```http
GET /api/v1/observations/:id
```
Response includes detections:
```json
{
"id": "uuid",
"imageUrl": "...",
"angle": "front",
"status": "analyzed",
"detections": [
{
"componentType": "card_reader",
"confidence": 0.95,
"boundingBox": {
"x": 0.1,
"y": 0.2,
"width": 0.3,
"height": 0.1
},
"isAnomaly": false
}
]
}
```
#### Compare with Baseline
```http
GET /api/v1/observations/:id/compare
```
Response:
```json
{
"observationId": "uuid",
"isSignificant": true,
"changeType": "structural",
"metrics": {
"pixelDifference": 0.15,
"structuralDifference": 0.25,
"overallDifference": 0.20
},
"confidence": 0.92,
"diffVisualization": "base64encoded..."
}
```
### Detections
#### List Detections
```http
GET /api/v1/detections
```
Query Parameters:
- `objectId` - Filter by object
- `componentType` - Filter by component (card_reader, pin_pad, etc.)
- `isAnomaly` - Filter anomalies (true/false)
- `severity` - Filter by severity (low, medium, high, critical)
#### Verify Detection
```http
POST /api/v1/detections/:id/verify
```
Request Body:
```json
{
"isCorrect": true,
"correctedType": "card_reader",
"notes": "Verified by security team"
}
```
### Alerts
#### List Alerts
```http
GET /api/v1/alerts
```
Query Parameters:
- `status` - open, acknowledged, investigating, resolved, false_positive
- `riskLevel` - green, yellow, orange, red
- `objectId` - Filter by object
#### Update Alert Status
```http
PUT /api/v1/alerts/:id/status
```
Request Body:
```json
{
"status": "resolved",
"resolution": "False positive - approved maintenance",
"assignedTo": "user-uuid"
}
```
#### Escalate Alert
```http
POST /api/v1/alerts/:id/escalate
```
Request Body:
```json
{
"reason": "Potential skimmer device detected",
"escalateTo": "security-team"
}
```
### Dashboard
#### Overview Statistics
```http
GET /api/v1/dashboard/overview
```
Response:
```json
{
"summary": {
"totalObjects": 150,
"activeAlerts": 12,
"recentObservations": 45,
"overdueObjects": 3,
"compliance": "98.0"
},
"objectStats": {
"green": 130,
"yellow": 10,
"orange": 5,
"red": 2
},
"alertRiskStats": {
"orange": 8,
"red": 4
}
}
```
#### Map Objects
```http
GET /api/v1/dashboard/objects
```
Query Parameters:
- `bounds` - Geo bounds: `{"sw":{"lat":59.3,"lng":18.0},"ne":{"lat":59.4,"lng":18.1}}`
- `status` - Filter by status
#### Activity Timeline
```http
GET /api/v1/dashboard/timeline?days=7
```
Response:
```json
{
"observations": [
{"date": "2026-07-01", "count": 15},
{"date": "2026-07-02", "count": 20}
],
"alerts": [
{"date": "2026-07-01", "riskLevel": "orange", "count": 2}
]
}
```
#### Top Priority Alerts
```http
GET /api/v1/dashboard/top-alerts
```
## Webhooks
VIMS can send webhooks to your endpoint:
### Alert Webhook
```json
{
"event": "vims.alert",
"timestamp": "2026-07-08T12:00:00Z",
"data": {
"alertId": "uuid",
"riskLevel": "red",
"title": "Skimmer detected",
"message": "Potential skimmer device found on ATM",
"objectId": "uuid",
"customerId": "uuid"
}
}
```
### Observation Webhook
```json
{
"event": "vims.observation",
"timestamp": "2026-07-08T12:00:00Z",
"data": {
"observationId": "uuid",
"objectId": "uuid",
"status": "analyzed",
"riskLevel": "green"
}
}
```
## Error Responses
```json
{
"error": "Validation Error",
"message": "Missing required fields",
"fields": ["objectId", "angle"]
}
```
Status Codes:
- `200` - Success
- `201` - Created
- `400` - Bad Request
- `401` - Unauthorized
- `403` - Forbidden
- `404` - Not Found
- `409` - Conflict
- `500` - Internal Server Error