API Reference — Video Analysis
Endpoint untuk upload video rekaman, manajemen Job analisis offline, assign analitik, dan konfigurasi pipeline.
← Kembali ke Video Analysis
Panduan operator: upload video, assign analitik, pantau progres Job.
Otentikasi
Cara memperoleh dan menggunakan Bearer token JWT.
Semua endpoint memerlukan header Authorization: Bearer <token>. Basis URL mengikuti variabel lingkungan VITE_API_URL yang dikonfigurasi pada instalasi Lenz. Endpoint yang menggunakan {nvrServerId} di-proxy oleh backend API ke Media Server yang dikonfigurasi sebagai System Media Server — ganti {nvrServerId} dengan ID Media Server yang aktif.
Daftar & Detail Job
Endpoint teragregasi yang dipakai langsung oleh halaman Video Analysis. Berbeda dari endpoint /api/visionaire-media/{nvrServerId}/videos* di bawah (yang menangani upload mentah dan manajemen video per Media Server), endpoint di sini menggabungkan data video, stream internal yang menjalankannya, dan status analisisnya dalam satu respons — lengkap dengan paginasi, pencarian, filter status, dan histogram jumlah Job per status (counts) untuk badge tab.
analysis_status memiliki lima nilai: idle (belum di-assign analitik), scheduled (terjadwal), progressing (berjalan), completed (selesai), dan error. Halaman daftar melipat kelima nilai ini menjadi tiga tab: Belum Mulai (idle + scheduled), Berjalan (progressing), dan Selesai (completed + error).
Daftar Job
Authorization
bearerAuth In: header
Query Parameters
Filter berdasarkan Media Server tertentu (opsional)
Filter status, dipisah koma. Nilai valid: idle, scheduled, progressing, completed, error. Nilai tak dikenal diabaikan.
Pencarian case-insensitive pada original_filename atau video_id
Kolom pengurutan
"started_at""started_at" | "created_at" | "original_filename" | "file_size" | "duration" | "synced_at""desc""asc" | "desc"1Jumlah item per halaman; 0 berarti kembalikan semua item
20Response Body
application/json
curl -X GET "https://lenz.example.com/api/video-analysis?status=progressing%2Ccompleted"{ "data": { "videos": [ { "nvr_server_id": 1, "video_id": "vid_abc123", "instance": "main", "original_filename": "rekaman-cctv.mp4", "file_path": "/storage/videos/rekaman-cctv.mp4", "file_size": 104857600, "duration": 3600, "upload_status": "completed", "started_at": "2026-06-20T08:00:00Z", "ended_at": "2026-06-20T09:00:00Z", "started_at_src": "metadata", "started_at_src_info": "Diambil dari metadata file (Recorded_Date)", "created_at": "2026-06-20T10:00:00Z", "synced_at": "2026-06-20T10:01:00Z", "updated_at": "2026-06-20T10:02:00Z", "stream": { "stream_id": "f1e2d3c4-stream", "stream_name": "rekaman-cctv.mp4", "stream_address": "rtsp://media-server/offline/rekaman-cctv", "stream_node_num": 1, "active": true, "deleted_at": null }, "analysis_status": "progressing" } ], "pagination": { "current_page": 1, "per_page": 20, "total_items": 42, "total_pages": 3 }, "counts": { "idle": 5, "scheduled": 2, "progressing": 1, "completed": 30, "error": 4 }, "success": true }}Detail Job
Authorization
bearerAuth In: header
Path Parameters
ID Media Server
ID video
Response Body
application/json
application/json
curl -X GET "https://lenz.example.com/api/video-analysis/1/vid_abc123"{ "data": { "video": { "nvr_server_id": 1, "video_id": "vid_abc123", "instance": "main", "original_filename": "rekaman-cctv.mp4", "file_size": 104857600, "duration": 3600, "upload_status": "completed", "started_at": "2026-06-20T08:00:00Z", "started_at_src": "metadata", "started_at_src_info": "Diambil dari metadata file (Recorded_Date)", "updated_at": "2026-06-20T10:02:00Z", "stream": { "stream_id": "f1e2d3c4-stream", "stream_name": "rekaman-cctv.mp4", "stream_node_num": 1, "active": true, "deleted_at": null }, "analysis_status": "progressing" }, "success": true }}{ "data": { "success": false, "message": "video not found in analysis view" }}Daftar Chunk Job
Authorization
bearerAuth In: header
Path Parameters
ID Media Server
ID video
Response Body
application/json
application/json
curl -X GET "https://lenz.example.com/api/video-analysis/1/vid_abc123/chunks"{ "data": { "parent_stream_id": "f1e2d3c4-stream", "chunks": [ { "stream_id": "chunk-stream-0", "stream_name": "rekaman-cctv.mp4_chunk_0", "stream_node_num": 1, "active": true, "updated_at": "2026-06-20T10:05:00Z", "deleted_at": null }, { "stream_id": "chunk-stream-1", "stream_name": "rekaman-cctv.mp4_chunk_1", "stream_node_num": 1, "active": true, "updated_at": "2026-06-20T10:05:30Z", "deleted_at": null } ], "success": true }}{ "data": { "success": false, "message": "video has no parent stream" }}Upload Video
Endpoint untuk mengunggah file video rekaman secara bertahap (chunked upload). File besar dikirim dalam potongan-potongan kecil menggunakan session_id yang sama. Sistem mendukung resume — jika koneksi terputus, lanjutkan dari chunk terakhir tanpa mengulang dari awal.
Unggah Chunk Video
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
Query Parameters
Jika true, video otomatis diputar sebagai stream RTSP setelah upload selesai.
trueRequest Body
multipart/form-data
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X POST "https://lenz.example.com/api/visionaire-media/0/videos/upload" \ -F file="string" \ -F filename="rekaman-2026-01.mp4" \ -F chunk_index="0" \ -F total_chunks="10" \ -F total_size="104857600"{ "success": true, "data": { "message": "Chunk received", "session_id": "sess-abc123", "video_id": "abc123def456", "chunk_index": 0, "chunks_received": 1, "total_chunks": 10, "bytes_written": 10485760, "total_size": 104857600, "progress": 10, "status": "uploading", "seq": 1, "instance": null }}Status Upload
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
ID sesi upload yang dikembalikan saat chunk pertama diterima.
Response Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire-media/0/videos/upload/status/string"{ "success": true, "data": { "session_id": "sess-abc123", "video_id": "abc123def456", "original_filename": "rekaman-2026-01.mp4", "status": "uploading", "bytes_written": 52428800, "total_size": 104857600, "chunks_received": 5, "total_chunks": 10, "progress": 50, "created_at": "2026-01-15T08:00:00Z", "updated_at": "2026-01-15T08:02:30Z" }}Cek Resume Upload
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
ID sesi upload yang ingin dilanjutkan.
Query Parameters
Nama file asli (opsional, untuk verifikasi).
ID video yang terkait (opsional, untuk verifikasi).
Response Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire-media/0/videos/upload/resume/string"{ "success": true, "data": { "message": "Session found, can resume", "session_id": "sess-abc123", "video_id": "abc123def456", "original_filename": "rekaman-2026-01.mp4", "status": "paused", "chunks_received": 5, "total_chunks": 10, "bytes_written": 52428800, "total_size": 104857600, "progress": 50, "missing_chunks": [ 5, 6, 7, 8, 9 ], "can_reuse_session": true }}Batalkan Upload
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
ID sesi upload yang akan dibatalkan.
Response Body
application/json
curl -X POST "https://lenz.example.com/api/visionaire-media/0/videos/upload/cancel/string"{ "success": true, "message": "Upload cancelled successfully", "session_id": "sess-abc123"}Manajemen Video (Job)
Endpoint per-Media-Server untuk melihat, mengambil detail, memperbarui metadata, dan menghapus video yang telah diunggah. Setiap video yang diunggah mewakili satu Job analisis offline. Endpoint ini di-proxy ke Media Server; halaman daftar/detail Video Analysis sendiri membaca dari endpoint teragregasi /api/video-analysis di atas.
Daftar Video
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
Query Parameters
Pencarian parsial case-insensitive pada ID dan nama file video.
Kolom pengurutan.
"created_at""original_filename" | "file_size" | "duration" | "started_at" | "created_at"Arah pengurutan.
"desc""asc" | "desc"Nomor halaman (1-indexed).
11 <= valueJumlah item per halaman. Nilai 0 mengembalikan semua item.
100 <= valueResponse Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire-media/0/videos"{ "success": true, "data": { "videos": [ { "id": "abc123def456", "original_filename": "rekaman-2026-01.mp4", "file_path": "/storage/videos/rekaman-2026-01.mp4", "file_size": 104857600, "created_at": "2026-01-15T08:00:00Z", "status": "streaming", "duration": 3600, "started_at": "2026-01-15T00:00:00Z", "started_at_src": "metadata", "ended_at": "2026-01-15T01:00:00Z", "instance": null } ], "count": 1, "pagination": { "current_page": 1, "per_page": 10, "total_items": 1, "total_pages": 1 } }}Detail Video
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
ID unik video.
Response Body
application/json
application/json
curl -X GET "https://lenz.example.com/api/visionaire-media/0/videos/string"{ "success": true, "data": { "video": { "id": "abc123def456", "original_filename": "rekaman-2026-01.mp4", "file_path": "/storage/videos/rekaman-2026-01.mp4", "file_size": 104857600, "created_at": "2026-01-15T08:00:00Z", "status": "streaming", "duration": 3600, "started_at": "2026-01-15T00:00:00Z", "started_at_src": "metadata", "ended_at": "2026-01-15T01:00:00Z", "device": { "name": "rekaman-2026-01", "url": "file:///storage/videos/rekaman-2026-01.mp4", "scheme": "file", "channel": "live", "silent_audio": false, "status": "running", "publish_url": "rtsp://192.168.1.10:1935/live/rekaman-2026-01", "created_at": "2026-01-15T08:00:00Z", "updated_at": "2026-01-15T08:01:00Z", "error_count": 0, "restart_count": 0, "uptime": 3600000 }, "instance": null } }}{ "success": false, "message": "video not found"}Perbarui Metadata Video
Memperbarui metadata video, misalnya menyetel ulang timestamp awal rekaman (started_at) setelah upload — nilai ini menentukan korelasi waktu event di Event History.
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
ID unik video.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X PATCH "https://lenz.example.com/api/visionaire-media/0/videos/string" \ -H "Content-Type: application/json" \ -d '{ "started_at": "2026-01-15T00:00:00Z", "started_at_src": "manual" }'{ "success": true, "data": { "video": { "id": "abc123def456", "original_filename": "rekaman-2026-01.mp4", "file_size": 104857600, "created_at": "2026-01-15T08:00:00Z", "status": "streaming", "duration": 3600, "started_at": "2026-01-15T00:00:00Z", "started_at_src": "manual" } }}Hapus Video
Authorization
bearerAuth In: header
Path Parameters
ID numerik Media Server (NVR).
ID unik video.
Response Body
application/json
curl -X DELETE "https://lenz.example.com/api/visionaire-media/0/videos/string"{ "success": true, "message": "Video deleted successfully", "video_id": "abc123def456"}Katalog Analitik
Endpoint untuk mengambil daftar analitik yang tersedia di instance Visionaire — digunakan untuk mengisi dropdown pemilihan analitik saat assign ke video. Field free_seats menunjukkan berapa seat lisensi masih tersedia untuk analitik tersebut.
Daftar Analitik Tersedia
Authorization
bearerAuth In: header
Query Parameters
ID instance spesifik pada mode federation (opsional)
Jika true, gabungkan data dari seluruh instance pada mode federation
Response Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire/analytic_list"{ "analytic_num": 2, "analytics": [ { "id": "NFDSS-FR", "name": "Face Recognition", "description": "Deteksi dan pengenalan wajah", "publisher": "Nodeflux", "type": "fr", "major_version": 4, "minor_version": 2, "free_seats": 3, "all_seats": 5, "seats": [ { "serial_number": "SN-001", "active_status": true }, { "serial_number": "SN-002", "active_status": false } ] }, { "id": "NFDSS-LPR", "name": "License Plate Recognition", "description": "Pembacaan plat nomor kendaraan", "publisher": "Nodeflux", "type": "lpr", "major_version": 4, "minor_version": 1, "free_seats": 2, "all_seats": 4, "seats": [] } ], "code": 200, "deployment_key": "dk-abc123", "hardware_id": "hw-xyz456", "message": "success", "version": { "major": 4, "minor": 2, "patch": 1 }}Daftar Analitik Aktif di Pipeline
curl -X GET "https://lenz.example.com/api/visionaire_active_analytic_list"{ "ok": true, "message": "successfully get active analytic list", "data": { "analytic_num": 1, "analytics": [ { "id": "NFDSS-FR", "name": "Face Recognition", "description": "Deteksi dan pengenalan wajah", "publisher": "Nodeflux", "type": "fr", "major_version": 4, "minor_version": 2, "free_seats": 3, "all_seats": 5, "seats": [] } ] }}Assignment Pipeline
Endpoint untuk men-assign, memperbarui, dan menghapus analitik pada stream internal yang dibuat dari video yang diunggah. Setelah upload selesai, sistem membuat stream internal dengan offline_mode: true — gunakan nodeId dan streamId dari stream tersebut untuk endpoint ini.
Sistem tidak mengizinkan assign analitik baru saat analisis sedang berjalan (running) atau terjadwal (scheduled). Tunggu hingga analisis selesai, atau batalkan jadwal terlebih dahulu sebelum menambah analitik baru.
Detail Pipeline Assignment
Authorization
bearerAuth In: header
Path Parameters
ID node tempat stream berjalan.
ID stream video.
ID analitik yang ditugaskan.
Query Parameters
ID instance pada mode federation (opsional).
Response Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire/pipeline/node-001/stream-uuid-001/NFV4-MPA"{ "analytic_id": "NFV4-MPA", "code": 200, "message": "success", "node_num": 1, "stream_id": "stream-uuid-001", "config": { "args": {}, "env": {}, "object_confidence_threshold": 0.5, "sub_analytics": [ { "name": "counting", "is_active": true, "areas": [ { "name": "Pintu Masuk", "points": [ { "x": 0.2, "y": 0.5 }, { "x": 0.8, "y": 0.5 } ], "direction": "both" } ], "object_confidence_threshold": 0.5 } ] }}Buat Pipeline Assignment
Authorization
bearerAuth In: header
Path Parameters
ID node tempat stream berjalan.
ID stream video.
ID analitik yang ditugaskan.
Query Parameters
ID instance pada mode federation (opsional).
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X POST "https://lenz.example.com/api/visionaire/pipeline/node-001/stream-uuid-001/NFV4-MPA" \ -H "Content-Type: application/json" \ -d '{ "sub_analytics": [ { "name": "counting", "is_active": true, "areas": [ { "name": "Pintu Masuk", "points": [ { "x": 0.2, "y": 0.5 }, { "x": 0.8, "y": 0.5 } ], "direction": "both" } ], "object_confidence_threshold": 0.5 } ] }'{ "analytic_id": "NFV4-MPA", "code": 200, "message": "success", "node_num": 1, "stream_id": "stream-uuid-001", "ok": true}Perbarui Pipeline Assignment
Authorization
bearerAuth In: header
Path Parameters
ID node tempat stream berjalan.
ID stream video.
ID analitik yang ditugaskan.
Query Parameters
ID instance pada mode federation (opsional).
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X PUT "https://lenz.example.com/api/visionaire/pipeline/node-001/stream-uuid-001/NFV4-MPA" \ -H "Content-Type: application/json" \ -d '{ "sub_analytics": [ { "name": "counting", "is_active": true, "areas": [ { "name": "Pintu Masuk — Revisi", "points": [ { "x": 0.1, "y": 0.5 }, { "x": 0.9, "y": 0.5 } ], "direction": "in" } ], "object_confidence_threshold": 0.6 } ] }'{ "analytic_id": "NFV4-MPA", "code": 200, "message": "success", "node_num": 1, "stream_id": "stream-uuid-001", "ok": true}Hapus Pipeline Assignment
Authorization
bearerAuth In: header
Path Parameters
ID node tempat stream berjalan.
ID stream video.
ID analitik yang ditugaskan.
Query Parameters
ID instance pada mode federation (opsional).
Response Body
application/json
curl -X DELETE "https://lenz.example.com/api/visionaire/pipeline/node-001/stream-uuid-001/NFV4-MPA"{ "analytic_id": "NFV4-MPA", "code": 200, "message": "success", "node_num": 1, "stream_id": "stream-uuid-001", "ok": true}Konfigurasi Analitik
Endpoint untuk mengambil konfigurasi default dan skema form analitik — digunakan saat membangun UI form konfigurasi pipeline, serta untuk memvalidasi konfigurasi raw JSON sebelum diterapkan.
Konfigurasi Default Analitik
Authorization
bearerAuth In: header
Path Parameters
ID analitik
Response Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire/analytics/NFDSS-FR/config"{ "analytic_id": "NFDSS-FR", "configs": [ { "name": "object_confidence_threshold", "type": "number", "label": "Confidence Threshold", "description": "Ambang batas kepercayaan deteksi (0.0 – 1.0)", "value": 0.5, "required": false, "min": 0, "max": 1, "step": 0.01 } ], "sub_analytics": [], "message": "success", "ok": true}Skema Form Konfigurasi Analitik
Authorization
bearerAuth In: header
Path Parameters
ID analitik
Response Body
application/json
curl -X GET "https://lenz.example.com/api/visionaire/analytics/NFDSS-FR/config/form"{ "analytic_id": "NFDSS-FR", "configs": [ { "name": "object_confidence_threshold", "type": "number", "label": "Confidence Threshold", "description": "Ambang batas kepercayaan deteksi (0.0 – 1.0)", "value": 0.5, "required": false, "min": 0, "max": 1, "step": 0.01 } ], "sub_analytics": [ { "name": "counting", "display_name": "Counting", "configs": [] } ], "message": "success", "ok": true}Validasi Konfigurasi Pipeline (JSON)
Authorization
bearerAuth In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST "https://lenz.example.com/api/visionaire/analytics/config/validate" \ -H "Content-Type: application/json" \ -d '{ "analytic_id": "NFDSS-FR", "config": "{\\"object_confidence_threshold\\": 0.7, \\"areas\\": []}", "logic": null }'{ "valid": true, "errors": [], "parsed_config": { "object_confidence_threshold": 0.7, "areas": [] }, "message": "configuration is valid", "ok": true}{ "valid": false, "errors": [ "object_confidence_threshold must be between 0 and 1" ], "parsed_config": null, "message": "configuration validation failed", "ok": false}Video Analysis
Unggah file video rekaman dan jalankan analitik AI secara offline — untuk investigasi dan audit dari rekaman yang ada di luar NVR.
Assignment
Konfigurasi dan tugaskan analitik AI ke video stream tertentu — mulai dari pemilihan analitik, penggambaran Region of Interest, hingga penyimpanan konfigurasi Pipeline.