Nodeflux Central
Streams

API Reference — Streams

Endpoint untuk mengelola Stream (CCTV/RTSP/RTMP), statistik, Site assignment, dan status node Visionaire.

Semua endpoint memerlukan header Authorization: Bearer <token>. Basis URL mengikuti variabel lingkungan VITE_API_URL yang dikonfigurasi pada instalasi Lenz. Jika Anda belum punya token, lihat halaman Otentikasi.


CRUD Stream

Endpoint utama untuk membuat, membaca, memperbarui, dan menghapus Stream satu per satu. Setiap Stream diidentifikasi secara unik oleh kombinasi Node ID dan Stream ID.

Daftar Stream

GET
/api/streams

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

page?integer

Nomor halaman, dimulai dari 1.

Default1
limit?integer

Jumlah item per halaman.

Default20
filter[stream_name]?string

Filter berdasarkan nama Stream (pencarian parsial).

filter[stream_status]?string

Filter berdasarkan status konektivitas Stream.

Value in"online" | "offline"
filter[site_id]?integer

Filter Stream berdasarkan ID Site.

filter[active]?boolean

Filter berdasarkan status aktif (true) atau nonaktif (false) Stream.

filter[analytic_id]?string

Filter Stream yang menjalankan analitik tertentu. Contoh: NFDSS-FR.

filter[node_num]?integer

Filter Stream berdasarkan nomor node Visionaire.

filter[tags]?string

Filter berdasarkan tag. Untuk multi-tag, pisahkan dengan koma. Contoh: outdoor,entrance.

instance?string

ID instance untuk mode Federation. Kosongkan untuk non-federation.

is_aggregated?boolean

Jika true, agregasi Stream dari seluruh instance Federation. Otomatis diset saat Federation aktif dan instance tidak diisi.

Response Body

application/json

curl -X GET "https://lenz.example.com/api/streams"
{  "ok": true,  "message": "success",  "data": {    "stream_number": 3,    "limit": 20,    "current_page": 1,    "total_data": 3,    "total_page": 1,    "streams": [      {        "stream_id": "abc123def456",        "stream_name": "Kamera Lobby Utama",        "stream_address": "rtsp://192.168.1.100:554/stream1",        "stream_node_num": 1,        "active": true,        "online": true,        "pipelines": [          "NFDSS-FR"        ],        "pipelines_history": [          "NFDSS-FR"        ],        "stream_sites": [          {            "stream_site_id": 1,            "stream_site_name": "Gedung A"          }        ],        "tags": [          "outdoor",          "entrance"        ],        "stream_latitude": -6.2088,        "stream_longitude": 106.8456,        "stream_stats": {          "fps": 25,          "frame_width": 1920,          "frame_height": 1080,          "state": "running",          "last_error_msg": "",          "last_activity_ts": 1714450800        },        "stream_custom_data": {          "rtsp_transport": "tcp",          "fps_cap": 0,          "quality_level": 1,          "effort_level": 1,          "dynamic_mode": false,          "capture_metadata": false,          "full_color_range": false,          "resized_res": 0,          "udp_mode": 0        },        "stream_setting": {          "quality": 1,          "resolution": 0,          "fps": 0        },        "stream_playback_id": "",        "instance": "core",        "deleted_at": null      }    ]  }}

Detail Stream

GET
/api/streams/{nodeId}/{streamId}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

nodeId*string

Nomor node Visionaire tempat Stream diproses.

streamId*string

ID unik Stream dalam node tersebut.

Query Parameters

instance?string

ID instance untuk mode Federation (opsional).

Response Body

application/json

curl -X GET "https://lenz.example.com/api/streams/string/string"
{  "ok": true,  "message": "success",  "stream": {    "stream_id": "abc123def456",    "stream_name": "Kamera Lobby Utama",    "stream_address": "rtsp://192.168.1.100:554/stream1",    "stream_node_num": 1,    "active": true,    "online": true,    "pipelines": [      "NFDSS-FR"    ],    "pipelines_history": [      "NFDSS-FR",      "NFDSS-LPR"    ],    "analytics": [      {        "analytic_id": "NFDSS-FR",        "active_logics": [          "face_recognition"        ]      }    ],    "analytics_history": [      {        "analytic_id": "NFDSS-LPR",        "active_logics": []      }    ],    "stream_sites": [      {        "stream_site_id": 1,        "stream_site_name": "Gedung A"      }    ],    "tags": [      "outdoor"    ],    "stream_latitude": -6.2088,    "stream_longitude": 106.8456,    "stream_stats": {      "fps": 25,      "frame_width": 1920,      "frame_height": 1080,      "state": "running",      "last_error_msg": "",      "last_activity_ts": 1714450800    },    "stream_custom_data": {      "rtsp_transport": "tcp",      "fps_cap": 0,      "quality_level": 1,      "effort_level": 1,      "dynamic_mode": false,      "capture_metadata": false,      "full_color_range": false,      "resized_res": 0,      "udp_mode": 0    },    "stream_setting": {      "quality": 1,      "resolution": 0,      "fps": 0    },    "stream_playback_id": "play-abc123",    "instance": "core",    "deleted_at": null  }}

Tambah Stream

POST
/api/streams/{nodeId}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

nodeId*string

Nomor node Visionaire tempat Stream akan didaftarkan.

Query Parameters

instance?string

ID instance untuk 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/streams/string" \  -H "Content-Type: application/json" \  -d '{    "stream_node_num": 1,    "stream_name": "Kamera Gerbang Utama",    "stream_address": "rtsp://192.168.1.200:554/live/stream",    "stream_latitude": -6.2088,    "stream_longitude": 106.8456,    "active": true,    "check_capability": true,    "rtsp_transport": "tcp",    "site_ids": [      1,      2    ],    "tags": [      "entrance",      "outdoor"    ],    "stream_custom_data": {      "rtsp_transport": "tcp",      "fps_cap": 0,      "quality_level": 1,      "effort_level": 1,      "dynamic_mode": false,      "capture_metadata": false,      "full_color_range": false,      "resized_res": 0,      "udp_mode": 0    }  }'
{  "ok": true,  "message": "string",  "stream": {    "stream_id": "abc123def456",    "stream_name": "Kamera Lobby Utama",    "stream_address": "rtsp://192.168.1.100:554/stream1",    "stream_node_num": 1,    "active": true,    "online": true,    "pipelines": [      "NFDSS-FR"    ],    "pipelines_history": [      "NFDSS-FR",      "NFDSS-LPR"    ],    "analytics": [      {        "analytic_id": "NFDSS-FR",        "active_logics": [          "face_recognition"        ]      }    ],    "analytics_history": [      {        "analytic_id": "NFDSS-FR",        "active_logics": [          "face_recognition"        ]      }    ],    "stream_latitude": -6.2088,    "stream_longitude": 106.8456,    "stream_sites": [      {        "stream_site_id": 1,        "stream_site_name": "Gedung A"      }    ],    "stream_stats": {      "fps": 25,      "frame_height": 1080,      "frame_width": 1920,      "last_error_msg": "",      "state": "running",      "last_activity_ts": 1714450800,      "offline_processed_duration_ms": 0,      "offline_processed_frames": 0,      "offline_progress_percent": 0,      "offline_status": "string",      "offline_total_duration_ms": 0,      "offline_total_frames": 0    },    "stream_custom_data": {      "capture_metadata": false,      "dynamic_mode": false,      "effort_level": 1,      "fps_cap": 0,      "full_color_range": false,      "quality_level": 1,      "resized_res": 0,      "rtsp_transport": "tcp",      "udp_mode": 0,      "offline_mode": false,      "offline_start_ms": 0,      "offline_duration_ms": 0,      "offline_base_timestamp": 0,      "offline_status": "pending",      "offline_chunk_index": 0,      "offline_chunks": 0,      "offline_parent_stream_id": "string",      "schedule_at": 0    },    "stream_setting": {      "quality": 1,      "resolution": 0,      "fps": 0    },    "stream_playback_id": "",    "tags": [      "outdoor",      "entrance"    ],    "instance": "core",    "deleted_at": "2019-08-24T14:15:22Z"  }}

Update Stream

PUT
/api/streams/{nodeId}/{streamId}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

nodeId*string

Nomor node Visionaire tempat Stream diproses.

streamId*string

ID unik Stream dalam node tersebut.

Query Parameters

instance?string

ID instance untuk 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/streams/string/string" \  -H "Content-Type: application/json" \  -d '{    "stream_node_num": 1,    "stream_name": "Kamera Gerbang Utama (Updated)",    "stream_address": "rtsp://192.168.1.200:554/live/stream",    "stream_latitude": -6.2088,    "stream_longitude": 106.8456,    "active": true,    "check_capability": false,    "rtsp_transport": "tcp",    "site_ids": [      1    ],    "tags": [      "entrance"    ],    "stream_custom_data": {      "rtsp_transport": "tcp",      "fps_cap": 15,      "quality_level": 2,      "effort_level": 1,      "dynamic_mode": false,      "capture_metadata": false,      "full_color_range": false,      "resized_res": 0,      "udp_mode": 0    }  }'
{  "ok": true,  "message": "string",  "stream": {    "stream_id": "abc123def456",    "stream_name": "Kamera Lobby Utama",    "stream_address": "rtsp://192.168.1.100:554/stream1",    "stream_node_num": 1,    "active": true,    "online": true,    "pipelines": [      "NFDSS-FR"    ],    "pipelines_history": [      "NFDSS-FR",      "NFDSS-LPR"    ],    "analytics": [      {        "analytic_id": "NFDSS-FR",        "active_logics": [          "face_recognition"        ]      }    ],    "analytics_history": [      {        "analytic_id": "NFDSS-FR",        "active_logics": [          "face_recognition"        ]      }    ],    "stream_latitude": -6.2088,    "stream_longitude": 106.8456,    "stream_sites": [      {        "stream_site_id": 1,        "stream_site_name": "Gedung A"      }    ],    "stream_stats": {      "fps": 25,      "frame_height": 1080,      "frame_width": 1920,      "last_error_msg": "",      "state": "running",      "last_activity_ts": 1714450800,      "offline_processed_duration_ms": 0,      "offline_processed_frames": 0,      "offline_progress_percent": 0,      "offline_status": "string",      "offline_total_duration_ms": 0,      "offline_total_frames": 0    },    "stream_custom_data": {      "capture_metadata": false,      "dynamic_mode": false,      "effort_level": 1,      "fps_cap": 0,      "full_color_range": false,      "quality_level": 1,      "resized_res": 0,      "rtsp_transport": "tcp",      "udp_mode": 0,      "offline_mode": false,      "offline_start_ms": 0,      "offline_duration_ms": 0,      "offline_base_timestamp": 0,      "offline_status": "pending",      "offline_chunk_index": 0,      "offline_chunks": 0,      "offline_parent_stream_id": "string",      "schedule_at": 0    },    "stream_setting": {      "quality": 1,      "resolution": 0,      "fps": 0    },    "stream_playback_id": "",    "tags": [      "outdoor",      "entrance"    ],    "instance": "core",    "deleted_at": "2019-08-24T14:15:22Z"  }}

Hapus Stream

DELETE
/api/streams/{nodeId}/{streamId}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

nodeId*string

Nomor node Visionaire tempat Stream diproses.

streamId*string

ID unik Stream dalam node tersebut.

Query Parameters

instance?string

ID instance untuk mode Federation (opsional).

Response Body

application/json

curl -X DELETE "https://lenz.example.com/api/streams/string/string"
{  "success": true,  "message": "Stream berhasil dihapus"}

Statistik & Status

Endpoint ringan untuk widget dashboard, monitoring jumlah Stream per status, dan validasi kesehatan node sebelum pendaftaran Stream baru.

Ringkasan Stream

GET
/api/streams/summary

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

instance?string

ID instance untuk mode Federation (opsional).

is_aggregated?boolean

Jika true, agregasi data dari seluruh instance Federation.

Response Body

application/json

curl -X GET "https://lenz.example.com/api/streams/summary"
{  "ok": true,  "message": "success",  "data": {    "stream_ids": [      "abc123",      "def456",      "ghi789"    ],    "stream_number": 10,    "total_online": 8,    "total_offline": 1,    "total_disabled": 1,    "pipelines": [      "NFDSS-FR",      "NFDSS-LPR"    ]  }}

Status Node

GET
/api/visionaire/node_status

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

instance?string

ID instance untuk mode Federation (opsional).

is_aggregated?boolean

Jika true, agregasi node dari seluruh instance Federation.

Response Body

application/json

curl -X GET "https://lenz.example.com/api/visionaire/node_status"
{  "node_number": 2,  "nodes": [    {      "node_num": 1,      "status": "online",      "ip_address": "192.168.1.10",      "run_mode": "gpu",      "running_time_sec": 86400,      "instance": "core"    },    {      "node_num": 2,      "status": "offline",      "ip_address": "192.168.1.11",      "run_mode": "cpu",      "running_time_sec": 0,      "instance": "core"    }  ]}

Daftar Tag

GET
/api/streams/tags

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

instance?string

ID instance untuk mode Federation (opsional).

Response Body

application/json

curl -X GET "https://lenz.example.com/api/streams/tags"
{  "ok": true,  "message": "success",  "data": [    "outdoor",    "entrance",    "hd",    "parking",    "lobby"  ]}

Site Assignment

Endpoint untuk menetapkan Stream ke satu atau lebih Site sekaligus. Request ini bersifat pengganti penuh — seluruh daftar Site Stream sebelumnya akan digantikan oleh site_ids yang dikirim.

Tetapkan Sites ke Stream

POST
/api/streams/assign-sites

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

instance?string

ID instance untuk 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/streams/assign-sites" \  -H "Content-Type: application/json" \  -d '{    "stream_id": "abc123def456",    "site_ids": [      1,      3,      5    ]  }'
{  "ok": true,  "message": "Sites assigned successfully"}

Bulk Operations

Operasi bulk pada Stream (bulk delete, bulk disable, bulk enable, bulk assign-site) dilakukan secara iteratif di sisi klien menggunakan endpoint CRUD standar di atas — tidak ada endpoint batch khusus di backend. Untuk setiap Stream dalam seleksi:

  • Bulk DeleteDELETE /api/streams/{nodeId}/{streamId} per Stream.
  • Bulk DisablePUT /api/streams/{nodeId}/{streamId} dengan active: false, mempertahankan field lain.
  • Bulk EnablePUT /api/streams/{nodeId}/{streamId} dengan active: true, mempertahankan field lain.
  • Bulk Assign-to-SitePOST /api/streams/assign-sites dengan daftar node_id/stream_id dan site_ids target. Request ini sifatnya pengganti penuh untuk daftar Site stream tersebut.

Gunakan endpoint di atas untuk mengimplementasikan alur bulk pada integrasi Anda. Pertimbangkan throttling (mis. 5–10 request paralel) untuk menghindari membebani Visionaire saat memproses banyak stream.


Drawing Presets

Drawing preset menyimpan koordinat ROI (garis dan poligon) yang sudah digambar di halaman Assignment agar dapat digunakan ulang antar stream dengan sudut kamera serupa. Endpoint ini dipakai oleh tombol Preset di kanvas gambar.

Daftar Drawing Preset

GET
/api/streams/drawing-presets

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

analytic_id*string

ID analitik untuk memfilter preset.

logic?string

Logika spesifik untuk memfilter lebih lanjut (counting, dwelling, dll.) — opsional.

Response Body

application/json

curl -X GET "https://lenz.example.com/api/streams/drawing-presets?analytic_id=NFV4-MPA&logic=counting"
{  "ok": true,  "message": "success",  "data": [    {      "id": "preset-uuid-001",      "name": "Garis Pintu Utama",      "analytic_id": "NFV4-MPA",      "logic": "counting",      "shapes": [        {          "type": "line",          "id": "shape-01",          "name": "Line A",          "points": [            {              "x": 0.2,              "y": 0.5            },            {              "x": 0.8,              "y": 0.5            }          ],          "direction": "both",          "color": "#3b82f6"        }      ],      "created_by": 1,      "created_at": "2025-03-10T08:00:00Z",      "updated_at": null    }  ]}

Simpan Drawing Preset

POST
/api/streams/drawing-presets

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

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/streams/drawing-presets" \  -H "Content-Type: application/json" \  -d '{    "name": "Garis Pintu Utama",    "analytic_id": "NFV4-MPA",    "logic": "counting",    "shapes": [      {        "type": "line",        "id": "shape-01",        "name": "Line A",        "points": [          {            "x": 0.2,            "y": 0.5          },          {            "x": 0.8,            "y": 0.5          }        ],        "direction": "both",        "color": "#3b82f6"      }    ]  }'
{  "ok": true,  "message": "success",  "data": {    "id": "preset-uuid-002",    "name": "Garis Pintu Utama",    "analytic_id": "NFV4-MPA",    "logic": "counting",    "shapes": [],    "created_by": 1,    "created_at": "2025-06-01T09:00:00Z",    "updated_at": null  }}

Perbarui Drawing Preset

PUT
/api/streams/drawing-presets/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*string

UUID drawing preset.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

name*string

Nama baru untuk preset.

Response Body

application/json

curl -X PUT "https://lenz.example.com/api/streams/drawing-presets/preset-uuid-001" \  -H "Content-Type: application/json" \  -d '{    "name": "Garis Pintu Utama — Revisi"  }'
{  "ok": true,  "message": "success",  "data": {    "id": "preset-uuid-001",    "name": "Garis Pintu Utama — Revisi",    "analytic_id": "NFV4-MPA",    "logic": "counting",    "shapes": [],    "created_by": 1,    "created_at": "2025-03-10T08:00:00Z",    "updated_at": "2025-06-01T10:00:00Z"  }}

Hapus Drawing Preset

DELETE
/api/streams/drawing-presets/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Path Parameters

id*string

UUID drawing preset.

Response Body

application/json

curl -X DELETE "https://lenz.example.com/api/streams/drawing-presets/preset-uuid-001"
{  "ok": true,  "message": "success"}

On this page