API Reference — Alert History
Endpoint untuk mengambil daftar alert, detail, memperbarui status follow-up, mengekspor data Alert History, dan berlangganan alert real-time lewat WebSocket.
← Kembali ke Alert History
Panduan operator: filter, follow-up, dan ekspor data alert.
Otentikasi
API key untuk integrasi, Bearer token untuk sesi pengguna, dan otentikasi WebSocket.
Semua endpoint memerlukan otentikasi. Untuk integrasi, kirim header X-Api-Key: <key> di setiap request tanpa header Authorization. Bearer token (Authorization: Bearer <access_token>, berlaku 30 menit) hanya untuk aplikasi yang menampilkan login Lenz ke penggunanya sendiri dan wajib menyertakan X-Integration-Signature. Basis URL mengikuti variabel lingkungan VITE_API_URL yang dikonfigurasi pada instalasi Lenz. Lihat Otentikasi untuk memilih jalur yang tepat.
Daftar & Detail Alert
Endpoint utama untuk mengambil daftar alert yang telah ter-trigger dan detail satu alert berdasarkan ID-nya.
Daftar Alert History
Authorization
bearerAuth In: header
Query Parameters
Kursor pagination untuk memuat halaman berikutnya atau sebelumnya. Ambil dari field next_cursor atau prev_cursor di respons sebelumnya. Hilangkan parameter ini untuk halaman pertama.
Jumlah item per halaman. Maksimum: 100.
201 <= value <= 100Jika true, respons akan menyertakan total keseluruhan data yang cocok. Mengaktifkan mode cursor dan membutuhkan query COUNT tambahan.
falseNomor halaman untuk mode offset-based pagination (1-indexed). Digunakan saat mode cursor tidak diaktifkan.
11 <= valueSet ke cursor untuk secara eksplisit menggunakan cursor-based pagination.
"cursor"Urutan berdasarkan waktu pembuatan alert.
"desc""asc" | "desc"Urutan berdasarkan tingkat keparahan alert.
"asc" | "desc"Pencarian teks bebas pada alertable_id, nama Alert Rule, atau nama stream.
Batas awal rentang waktu dalam format ISO 8601 / RFC 3339.
date-timeBatas akhir rentang waktu dalam format ISO 8601 / RFC 3339.
date-timeFilter tingkat keparahan. Dapat berisi beberapa nilai dipisahkan koma.
Filter status follow-up. Dapat berisi beberapa nilai dipisahkan koma.
Filter berdasarkan ID Alert Rule tertentu.
Filter berdasarkan satu atau beberapa Stream ID, dipisahkan koma.
Filter berdasarkan ID site. Akan menampilkan alert dari semua stream yang berada di site tersebut.
Filter berdasarkan tipe sumber alert.
"event" | "manual" | "system" | "scheduled" | "external"Timezone klien (identifikasi IANA) untuk interpretasi filter tanggal.
"UTC"ID instance backend. Digunakan dalam mode Federation untuk mengambil alert dari instance tertentu.
Response Body
application/json
application/json
application/json
application/json
curl -X GET "https://lenz.example.com/api/alert-history"{ "ok": true, "message": "successfully get alert history list", "data": [ { "id": 1042, "alertable_id": "event_stream-uuid-xyz_1746000898", "alertable_type": "event", "alert_rule_id": 7, "severity": "critical", "follow_up_status": "not_followed_up", "follow_up_notes": null, "created_at": "2025-04-30T08:15:00Z", "updated_at": null, "instance": null, "alert_rule": { "id": 7, "name": "Deteksi Wajah Tidak Dikenal", "description": "Alert untuk wajah yang tidak terdaftar di enrollment", "active": true, "analytic_id": "FR" }, "event": { "id": 5801, "analytic_id": "FR", "stream_id": "stream-uuid-xyz", "stream_name": "Pintu Masuk Utama", "primary_image": "<base64-encoded-image>", "label": "Unknown", "result": "unknown", "event_time": "2025-04-30T08:14:58Z", "created_at": "2025-04-30T08:14:59Z" } } ], "pagination": { "limit": 20, "has_next": true, "has_prev": false, "next_cursor": "eyJ0IjoiMjAyNS0wNC0zMFQwODoxNTowMFoiLCJpZCI6IjEwMzAifQ==", "prev_cursor": null, "total": null }}{ "ok": false, "code": "bad-request", "errors": [ "invalid cursor format" ], "message": "Invalid query parameters"}{ "ok": false, "code": "unauthorized", "message": "Authentication required"}{ "ok": false, "code": "forbidden", "message": "Access denied: alert_history permission required"}Detail Alert
Authorization
bearerAuth In: header
Path Parameters
ID numerik alert history.
Query Parameters
ID instance backend. Digunakan dalam mode Federation.
Response Body
application/json
application/json
curl -X GET "https://lenz.example.com/api/alert-history/1042"{ "ok": true, "message": "successfully get alert history detail", "data": { "id": 1042, "alertable_id": "event_stream-uuid-xyz_1746000898", "alertable_type": "event", "alert_rule_id": 7, "severity": "critical", "follow_up_status": "not_followed_up", "follow_up_notes": null, "created_at": "2025-04-30T08:15:00Z", "updated_at": null, "instance": null, "alert_rule": { "id": 7, "name": "Deteksi Wajah Tidak Dikenal", "description": "Alert untuk wajah yang tidak terdaftar di enrollment", "active": true, "analytic_id": "FR" }, "event": { "id": 5801, "analytic_id": "FR", "stream_id": "stream-uuid-xyz", "stream_name": "Pintu Masuk Utama", "stream_latitude": -6.2088, "stream_longitude": 106.8456, "primary_image": "<base64-encoded-image>", "secondary_image": null, "label": "Unknown", "result": "unknown", "location": "Lantai 1, Gedung A", "status": "active", "logic": "face_recognition", "event_time": "2025-04-30T08:14:58Z", "created_at": "2025-04-30T08:14:59Z", "pipeline_event_id": "event_stream-uuid-xyz_1746000898" } }}{ "ok": false, "code": "not-found", "message": "Alert history record not found"}Detail Alert by Alertable
Authorization
bearerAuth In: header
Path Parameters
Tipe entitas alertable.
"event" | "manual" | "system" | "scheduled" | "external"ID unik entitas yang memicu alert.
Query Parameters
Timezone klien (identifikasi IANA).
"UTC"Response Body
application/json
application/json
application/json
curl -X GET "https://lenz.example.com/api/alert-history/by-alertable/event/event_stream-uuid-xyz_1746000898"{ "ok": true, "message": "successfully get alert history detail by alertable", "data": { "id": 1042, "alertable_id": "event_stream-uuid-xyz_1746000898", "alertable_type": "event", "alert_rule_id": 7, "severity": "critical", "follow_up_status": "not_followed_up", "follow_up_notes": null, "created_at": "2025-04-30T08:15:00Z", "updated_at": null, "instance": null, "alert_rule": { "id": 7, "name": "Deteksi Wajah Tidak Dikenal", "description": "Alert untuk wajah yang tidak terdaftar di enrollment", "active": true, "analytic_id": "FR" }, "event": { "id": 5801, "analytic_id": "FR", "stream_id": "stream-uuid-xyz", "stream_name": "Pintu Masuk Utama", "label": "Unknown", "result": "unknown", "event_time": "2025-04-30T08:14:58Z", "created_at": "2025-04-30T08:14:59Z" } }}{ "ok": false, "code": "bad-request", "errors": [ "invalid alertable_type" ], "message": "Invalid alertable_type. Must be one of: event, manual, system, scheduled, external"}{ "ok": false, "code": "not-found", "message": "Alert history record not found for the specified alertable_id and alertable_type"}Follow-up
Endpoint untuk memperbarui status follow-up satu alert. Status yang tersedia: not_followed_up (belum ditangani), followed_up (sudah ditangani, umum), match / not_match (hasil verifikasi identitas cocok / tidak cocok), expired (data sudah kedaluwarsa saat diperiksa), dan other (alasan lain — wajib mengisi reason).
Perbarui Status Follow-up
Authorization
bearerAuth In: header
Path Parameters
ID numerik alert history.
Query Parameters
ID instance backend. Digunakan dalam mode Federation.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X PATCH "https://lenz.example.com/api/alert-history/1042/follow-up-status" \ -H "Content-Type: application/json" \ -d '{ "follow_up_status": "followed_up", "follow_up_notes": "Sudah diperiksa oleh tim keamanan pukul 09.00 WIB" }'{ "ok": true, "message": "follow up status updated successfully"}{ "ok": false, "code": "bad-request", "message": "Invalid follow_up_status value"}{ "ok": false, "code": "not-found", "message": "Alert history record not found"}Ekspor
Endpoint untuk mengekspor data alert history secara asinkron ke format PDF atau Excel. Alur ekspor:
- Panggil Mulai Job Ekspor untuk memulai proses di sisi server. Respons berisi
job_id. - Polling Status Job Ekspor menggunakan
job_idhinggastatusbernilaicompleted. - Panggil Unduh Hasil Ekspor untuk mengunduh file binary.
- (Opsional) Panggil Batalkan Job Ekspor untuk membatalkan proses yang masih berjalan.
Ekspor dalam jumlah besar (ribuan alert dengan opsi include_images: true) dapat membutuhkan waktu lebih lama dan menghasilkan file berukuran signifikan. Gunakan filter rentang tanggal untuk membatasi cakupan data sebelum mengekspor.
Mulai Job Ekspor
Authorization
bearerAuth 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/alert-history/export" \ -H "Content-Type: application/json" \ -d '{ "format": "excel", "scope": "all", "timezone": "Asia/Jakarta", "include_images": false, "filters": { "created_from": "2025-04-01T00:00:00Z", "created_to": "2025-04-30T23:59:59Z", "severities": [ "critical", "warning" ] } }'{ "ok": true, "message": "Export job started", "data": { "job_id": "export-job-uuid-abc123", "status": "pending", "estimated_time_seconds": 30, "total_records": 500 }}Status Job Ekspor
Authorization
bearerAuth In: header
Path Parameters
ID job ekspor yang dikembalikan oleh endpoint Mulai Job Ekspor.
Response Body
application/json
curl -X GET "https://lenz.example.com/api/alert-history/export/status/export-job-uuid-abc123"{ "ok": true, "message": "success", "data": { "job_id": "export-job-uuid-abc123", "status": "completed", "progress": { "processed": 500, "total": 500, "percent": 100 }, "file_ready": true, "error_message": null, "created_at": "2025-04-30T08:00:00Z", "completed_at": "2025-04-30T08:00:45Z" }}Unduh Hasil Ekspor
Authorization
bearerAuth In: header
Path Parameters
ID job ekspor.
Response Body
application/json
curl -X GET "https://lenz.example.com/api/alert-history/export/download/export-job-uuid-abc123""string"{ "ok": false, "code": "not-found", "message": "Export job not found or file not ready"}Batalkan Job Ekspor
Authorization
bearerAuth In: header
Path Parameters
ID job ekspor yang akan dibatalkan.
Response Body
application/json
curl -X DELETE "https://lenz.example.com/api/alert-history/export/export-job-uuid-abc123"{ "ok": true, "message": "Export job cancelled"}Webhook & Streaming
Channel WebSocket untuk menerima alert secara real-time — jalur yang sama yang dipakai Lenz untuk memunculkan toast alert di pojok layar. Berbeda dengan /api/event_channel yang mengalirkan semua deteksi, channel ini hanya mengirim event yang sudah lolos minimal satu Alert Rule aktif, sehingga cocok untuk sistem eksternal yang hanya peduli pada kejadian signifikan (dashboard SOC, notifikasi ke aplikasi chat, alur otomasi).
Endpoint /api/alert_channel menggunakan protokol WebSocket — bukan HTTP biasa. Gunakan ws:// atau wss:// sebagai skema URL, dan kirim kredensial sebagai query parameter (x-api-key=<key> untuk integrasi, atau authorization=<access_token> untuk sesi pengguna) karena browser tidak bisa menyertakan header kustom saat handshake. Lihat Otentikasi WebSocket.
Beberapa perilaku yang perlu diperhatikan sebelum berlangganan:
- Cakupan mengikuti hak akses akun. Server hanya mengirim alert dari stream yang boleh diakses akun pemilik kredensial. Jika akun tidak punya akses ke stream mana pun, handshake ditolak dengan
403. - Filter ditentukan oleh Alert Rule, bukan query parameter. Parameter
stream_ids,analytic_id, danlogicmilik/api/event_channeldiabaikan di sini. Atur Alert Rule untuk memilih stream dan kondisi yang layak menjadi alert. - Payload tidak memuat
alert_history_id. Record alert history disimpan secara asinkron setelah pesan terkirim. Untuk menautkan pesan ke record REST, gunakanstream_iddantimestamppada payload sebagai filterfilter[stream_id]+filter[created_from]/filter[created_to]di Daftar Alert History. - Konsumsi pesan dengan cepat. Server mem-buffer maksimal 256 pesan per koneksi; jika buffer penuh, koneksi ditutup. Pada volume tinggi gunakan
disable_base64_image=truedan ambil gambar lewatGET /api/event/image?<primary_image_url>hanya saat dibutuhkan. - Federation. Tambahkan
is_aggregated=trueuntuk menerima alert dari instance lokal dan semua remote instance sekaligus. Event dari remote instance membawa fieldinstance, danprimary_image_url-nya sudah menyertakaninstance=sehingga bisa langsung dipakai. - Reconnect. Koneksi bisa terputus saat server restart atau jaringan bermasalah. Terapkan reconnect otomatis dengan exponential backoff seperti yang dilakukan Lenz (basis 5 detik, maksimum 10 percobaan).
import WebSocket from 'ws';
const params = new URLSearchParams({
'x-api-key': process.env.LENZ_API_KEY,
disable_base64_image: 'true',
});
const ws = new WebSocket(`wss://api.contoh.com/api/alert_channel?${params}`);
ws.on('message', (data) => {
const alert = JSON.parse(data.toString());
console.log(`[alert_type ${alert.alert_type_id}] ${alert.analytic_id} @ ${alert.stream_id}`);
// gambar: GET https://api.contoh.com/api/event/image?${alert.primary_image_url}
});
ws.on('close', () => {
// implementasikan reconnect dengan exponential backoff
});WebSocket Alert Channel
Query Parameters
API key untuk integrasi. Wajib salah satu dari x-api-key atau authorization.
Access token sesi pengguna (berlaku 30 menit), dengan atau tanpa awalan Bearer . Alternatif dari x-api-key.
Set true agar primary_image/secondary_image tidak disertakan; ambil gambar lewat primary_image_url saat dibutuhkan. Sangat disarankan pada volume tinggi.
falseMode Federation: set true untuk menerima alert dari instance lokal dan semua remote instance. Lenz mengaktifkan ini otomatis saat berjalan dalam mode Federation.
falseMode Federation: berlangganan hanya ke satu remote instance tertentu. Kosongkan atau isi core untuk instance lokal.
Response Body
application/json
application/json
curl -X GET "https://lenz.example.com/api/alert_channel?x-api-key=%3Ckey%3E&authorization=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."{ "event_id": "3f1a9c2e-7b4d-4e0a-9c1b-2d5f6a7b8c9d", "alert_type_id": 2, "analytic_id": "NFV4-FR", "stream_id": "eb7022a64d9173a6", "node_num": 0, "label": "UNKNOWN", "location": "Lobby Utama", "result": "UNKNOWN", "status": "UNKNOWN", "logic": "face_recognition", "timestamp": "2026-04-30T08:23:45+07:00", "instance": "cabang-bandung", "primary_image": "string", "secondary_image": "string", "primary_image_url": "event_id=3f1a9c2e-7b4d-4e0a-9c1b-2d5f6a7b8c9d&type=primary", "secondary_image_url": "event_id=3f1a9c2e-7b4d-4e0a-9c1b-2d5f6a7b8c9d&type=secondary", "pipeline_data": { "face_id": "118747588341006337", "similarity": 0.4894, "status": "UNKNOWN", "confidence_detection": 0.9988 }}{ "ok": false, "code": "forbidden", "message": "you don't have access to any streams"}