Dokumentasi / AI Box Dan Software Analitik Video / Referensi API
API Platform AI Box
Bagian dasbor ARSA AI Box Series yang sama di setiap produk: lokasi dan zonanya, kamera dan apa yang digambar di atasnya, video langsung dan rekaman, peringatan, kontak dan webhook peringatan, sirene dan relai, laporan, serta webhook untuk integrator. Setiap produk menambahkan API-nya sendiri di samping API ini, di bawah /api/<product>/v1.
Memanggil API
Kirim token akun API di header Authorization: Authorization: Bearer <API_KEY>. Admin membuat akun di dasbor (Akun API); token ditampilkan satu kali. Token hanya melihat lokasi tempat akunnya memiliki peran, dan hanya apa yang diizinkan cakupannya (read, write, export, personal_data). Setiap operasi menyebutkan siapa yang dapat memanggilnya dan cakupan yang diperlukan. Dasbor melayani HTTPS dengan sertifikat milik perangkat: Admin mengunduh salinannya (box.pem) di dasbor (Sistem, lalu Akun API, lalu Unduh sertifikat perangkat) beserta sidik jari SHA-256-nya, dan token dengan read dapat mengambilnya dengan getBoxCertificate. Periksa sidik jarinya sebelum klien Anda memercayai berkas itu.
Galat berupa problem details RFC 9457 (application/problem+json) dengan code yang tetap. Waktu memakai RFC 3339; angka per jam dan per hari mengikuti zona waktu lokasi. Daftar panjang dibagi per halaman: berikan limit, lalu next_before dari jawaban sebagai before. Panggilan dibatasi per akun API (bawaan 600 per menit; setelah itu 429 dengan Retry-After).
Webhook untuk Integrator
Akun API dapat mendaftarkan penerimanya sendiri (/webhook-subscriptions): peristiwa deteksi dalam batch, ringkasan berkala dan peringatan, ditandatangani dengan cara Standard Webhooks. Panduan webhook menjelaskan isi kiriman, tanda tangan dan percobaan ulang.
1.0.0
Lokasi Dan Zona
Lokasi (pabrik, toko, koridor) dan zona di dalamnya.
Lokasi Tempat Akun API Memiliki Peran
GET/sites
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"name": "North Plant",
"timezone": "Asia/Jakarta",
"created": "2026-10-01T02:00:00Z",
"version": 4,
"my_role": "viewer",
"location": {
"lat": -6.2,
"lon": 106.8
},
"area": null,
"zones": 3
},
{
"id": 2,
"name": "Warehouse B",
"timezone": "Asia/Jakarta",
"created": "2026-10-03T02:00:00Z",
"version": 1,
"my_role": "admin",
"location": null,
"area": null,
"zones": 0
}
]
}Satu Lokasi
GET/sites/{id}
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"name": "North Plant",
"timezone": "Asia/Jakarta",
"created": "2026-10-01T02:00:00Z",
"version": 4,
"my_role": "viewer",
"location": {
"lat": -6.2,
"lon": 106.8
},
"area": null,
"zones": 3
}Ganti Nama Lokasi, Ubah Zona Waktunya, Atau Tempatkan Di Peta (Titik, Batas)
PATCH/sites/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
name | string | |
timezone | string | |
location | one of | Titik lokasi; null menghapusnya. |
area | one of | Batas wilayah; null menghapusnya. |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/sites/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","timezone":"Asia/Jakarta","location":{"lat":-6.2,"lon":106.8},"area":[[12,12],[12,12],[12,12]]}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/sites/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"timezone": "Asia/Jakarta",
"location": {
"lat": -6.2,
"lon": 106.8
},
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
]
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"timezone": "Asia/Jakarta",
"location": {
"lat": -6.2,
"lon": 106.8
},
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
]
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"name": "Main gate",
"timezone": "Asia/Jakarta",
"created": "2026-11-02T08:00:00Z",
"version": 3,
"my_role": "admin",
"location": {
"lat": -6.2,
"lon": 106.8
},
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
],
"zones": 12
}Zona Lokasi
GET/sites/{id}/zones
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1/zones" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1/zones",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/zones", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
],
"created": "2026-11-02T08:00:00Z",
"version": 3
}
]
}Tambahkan Zona Ke Lokasi
POST/sites/{id}/zones
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
namewajib | string | |
area | one of |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/sites/1/zones" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","area":[[12,12],[12,12],[12,12]]}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/sites/1/zones",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
]
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/zones", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
]
}),
});
console.log(r.status, await r.text());Respons 201
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
],
"created": "2026-11-02T08:00:00Z",
"version": 3
}Ganti Nama Zona Atau Ubah Garis Batasnya
PATCH/sites/{id}/zones/{zone}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
zonewajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
name | string | |
area | one of | Garis batas; null menghapusnya. |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/sites/1/zones/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","area":[[12,12],[12,12],[12,12]]}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/sites/1/zones/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
]
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/zones/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
]
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"area": [
[
12,
12
],
[
12,
12
],
[
12,
12
]
],
"created": "2026-11-02T08:00:00Z",
"version": 3
}Hapus Zona (Kameranya Tetap Di Lokasi, Tanpa Zona)
DELETE/sites/{id}/zones/{zone}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
zonewajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/sites/1/zones/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/sites/1/zones/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/zones/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Kamera
Kamera, alirannya, apa yang digambar di atasnya (garis, zona, lajur) dan cuplikan gambar.
Kamera Di Lokasi Akun API
GET/cameras
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/cameras" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/cameras",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 11,
"name": "Gate 1",
"site_id": 1,
"zone_id": 2,
"password_set": true,
"over_licence": false,
"status": {
"running": true,
"capture": "streaming"
}
},
{
"id": 12,
"name": "Loading Bay",
"site_id": 1,
"zone_id": null,
"password_set": true,
"over_licence": false,
"status": {
"running": true,
"capture": "streaming"
}
}
]
}Tambahkan Kamera Ke Lokasi
POST/cameras
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
Idempotency-Key header | string |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
site_idwajib | integer | |
namewajib | string | |
rtsp_urlwajib | string | |
host | string | |
username | string | |
password | string | |
width | integer | |
height | integer | |
fps | integer |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/cameras" \
-H "Authorization: Bearer <API_KEY>" \
-H "Idempotency-Key: <IDEMPOTENCY_KEY>" \
-H "Content-Type: application/json" \
-d '{"site_id":1,"name":"Main gate","rtsp_url":"https://<RECEIVER_HOST>/hooks/arsa","host":"<host>","username":"<username>","password":"<password>","width":12,"height":12,"fps":12}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/cameras",
headers={"Authorization": "Bearer <API_KEY>", "Idempotency-Key": "<IDEMPOTENCY_KEY>"},
json={
"site_id": 1,
"name": "Main gate",
"rtsp_url": "https://<RECEIVER_HOST>/hooks/arsa",
"host": "<host>",
"username": "<username>",
"password": "<password>",
"width": 12,
"height": 12,
"fps": 12
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Idempotency-Key": "<IDEMPOTENCY_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"site_id": 1,
"name": "Main gate",
"rtsp_url": "https://<RECEIVER_HOST>/hooks/arsa",
"host": "<host>",
"username": "<username>",
"password": "<password>",
"width": 12,
"height": 12,
"fps": 12
}),
});
console.log(r.status, await r.text());Respons 201
{
"id": 1,
"name": "Main gate",
"rtsp_url": "https://<RECEIVER_HOST>/hooks/arsa",
"password_set": true,
"site_id": 1,
"status": {},
"over_licence": true,
"zone_id": 1
}Satu Kamera
GET/cameras/{id}
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/cameras/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/cameras/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"name": "Main gate",
"rtsp_url": "https://<RECEIVER_HOST>/hooks/arsa",
"password_set": true,
"site_id": 1,
"status": {},
"over_licence": true,
"zone_id": 1
}Ubah Kamera (JSON Merge Patch, If-Match)
PATCH/cameras/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
If-Match header | string | ETag yang dibaca sebelumnya; wajib untuk perubahan. |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
412 | ETag di If-Match sudah usang |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
428 | If-Match wajib diisi |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/cameras/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "If-Match: <IF_MATCH>"import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/cameras/1",
headers={"Authorization": "Bearer <API_KEY>", "If-Match": "<IF_MATCH>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "If-Match": "<IF_MATCH>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"name": "Main gate",
"rtsp_url": "https://<RECEIVER_HOST>/hooks/arsa",
"password_set": true,
"site_id": 1,
"status": {},
"over_licence": true,
"zone_id": 1
}Hapus Kamera
DELETE/cameras/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
If-Match header | string | ETag yang dibaca sebelumnya; wajib untuk perubahan. |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
412 | ETag di If-Match sudah usang |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/cameras/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "If-Match: <IF_MATCH>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/cameras/1",
headers={"Authorization": "Bearer <API_KEY>", "If-Match": "<IF_MATCH>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>", "If-Match": "<IF_MATCH>" },
});
console.log(r.status, await r.text());Tempatkan Kamera Di Salah Satu Zona Lokasinya, Atau Tanpa Zona
PUT/cameras/{id}/zone
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
zone_idwajib | integer | Zona di lokasi kamera itu sendiri, atau null untuk tanpa zona. |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PUT "https://<BOX_HOST>/api/v1/cameras/1/zone" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"zone_id":1}'import requests
r = requests.put(
"https://<BOX_HOST>/api/v1/cameras/1/zone",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"zone_id": 1
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1/zone", {
method: "PUT",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"zone_id": 1
}),
});
console.log(r.status, await r.text());Respons 200
{
"camera_id": 1,
"site_id": 1,
"zone_id": 1
}Geometri Kamera (Garis, Zona, Lajur)
GET/cameras/{id}/geometry
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/cameras/1/geometry" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/cameras/1/geometry",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1/geometry", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{}Ganti Geometri (If-Match)
PUT/cameras/{id}/geometry
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
If-Match header | string | ETag yang dibaca sebelumnya; wajib untuk perubahan. |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
412 | ETag di If-Match sudah usang |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
428 | If-Match wajib diisi |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X PUT "https://<BOX_HOST>/api/v1/cameras/1/geometry" \
-H "Authorization: Bearer <API_KEY>" \
-H "If-Match: <IF_MATCH>" \
-H "Content-Type: application/json" \
-d '{}'import requests
r = requests.put(
"https://<BOX_HOST>/api/v1/cameras/1/geometry",
headers={"Authorization": "Bearer <API_KEY>", "If-Match": "<IF_MATCH>"},
json={},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1/geometry", {
method: "PUT",
headers: { "Authorization": "Bearer <API_KEY>", "If-Match": "<IF_MATCH>", "Content-Type": "application/json" },
body: JSON.stringify({}),
});
console.log(r.status, await r.text());Respons 200
{}Bingkai Kamera Saat Ini
GET/cameras/{id}/snapshot
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | JPEG |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/cameras/1/snapshot" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/cameras/1/snapshot",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/cameras/1/snapshot", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Video Langsung Dan Rekaman
Tampilan langsung (WebRTC, HLS), segmen rekaman, ekspor MP4 dan klip peristiwa.
WHEP: Penawaran SDP Dari Peramban Untuk Siaran Langsung Kamera; Menjawab Dengan Jawaban SDP (RFC 9725)
POST/live/{camera}/whep
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: write, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
camerawajib path | integer |
Respons
| Status | Arti |
|---|---|
201 | jawaban SDP |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/live/1/whep" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/live/1/whep",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/live/1/whep", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Daftar Putar HLS Kamera (Cadangan Bila WebRTC Tidak Dapat Tersambung)
GET/live/{camera}/hls.m3u8
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: read, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
camerawajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/live/1/hls.m3u8" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/live/1/hls.m3u8",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/live/1/hls.m3u8", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Satu Segmen HLS
GET/live/{camera}/segments/{name}
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: read, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
camerawajib path | integer | |
namewajib path | string |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/live/1/segments/{name}" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/live/1/segments/{name}",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/live/1/segments/{name}", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Segmen Rekaman Kamera (Satu Kamera Per Kueri)
GET/recordings
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: read, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
camerawajib query | integer | |
from query | string | |
to query | string | |
cursor query | string | |
limit query | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/recordings?camera=1&from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&limit=50" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/recordings?camera=1&from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&limit=50",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/recordings?camera=1&from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&limit=50", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{}Ekspor Rekaman Kamera Hingga 60 Menit Ke MP4 (Berupa Job; Dicatat Di Log Audit)
POST/recordings/export
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: write, export, personal_data.
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
camerawajib | integer | |
fromwajib | date-time | |
towajib | date-time |
Respons
| Status | Arti |
|---|---|
202 | berupa job; pantau Location-nya (/api/v1/recordings/exports/{job}) |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/recordings/export" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"camera":12,"from":"2026-11-02T08:00:00Z","to":"2026-11-02T08:00:00Z"}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/recordings/export",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"camera": 12,
"from": "2026-11-02T08:00:00Z",
"to": "2026-11-02T08:00:00Z"
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/recordings/export", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"camera": 12,
"from": "2026-11-02T08:00:00Z",
"to": "2026-11-02T08:00:00Z"
}),
});
console.log(r.status, await r.text());Respons 202
{}Job Ekspor Atau Klip (Tautan File Ke Dasbor Setelah Selesai)
GET/recordings/exports/{job}
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: read, export, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
jobwajib path | string |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/recordings/exports/{job}" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/recordings/exports/{job}",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/recordings/exports/{job}", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{}MP4 Hasil Ekspor (Dialirkan; Rentang Byte)
GET/recordings/exports/{job}/file
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: read, export, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
jobwajib path | string |
Respons
| Status | Arti |
|---|---|
200 | OK |
206 | rentang byte |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/recordings/exports/{job}/file" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/recordings/exports/{job}/file",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/recordings/exports/{job}/file", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Klip Di Sekitar Suatu Peristiwa (Bawaan 10 Detik Sebelum Sampai 20 Detik Sesudah; Berupa Job; Dicatat Di Log Audit)
POST/events/{id}/clip
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi kamera tersebut. Cakupan token: write, export, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | string |
Respons
| Status | Arti |
|---|---|
202 | berupa job; pantau Location-nya (/api/v1/recordings/exports/{job}) |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
502 | Mesin analitik menolak permintaan (engine_refused) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/events/{id}/clip" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/events/{id}/clip",
headers={"Authorization": "Bearer <API_KEY>"},
json={},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/events/{id}/clip", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({}),
});
console.log(r.status, await r.text());Respons 202
{}Peringatan
Peringatan yang muncul dari deteksi; tampilkan daftarnya, baca satu, tandai sudah ditangani.
Peringatan, Terbaru Lebih Dulu
GET/alerts
Siapa yang dapat memanggil: Setiap akun API; jawabannya mencakup lokasi tempat akun itu memiliki peran. Cakupan token: read. Tanpa personal_data jawabannya berbentuk anonim: tanpa nama, nomor polisi, gambar atau rekaman.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
site query | integer | hanya lokasi ini |
state query | string | open atau acknowledged |
kind query | string | hanya jenis ini |
before query | integer | next_before dari halaman sebelumnya |
limit query | integer | 1..500, bawaan 50 |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/alerts?site=1&before=2026-11-02T08%3A00%3A00Z&limit=50" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/alerts?site=1&before=2026-11-02T08%3A00%3A00Z&limit=50",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/alerts?site=1&before=2026-11-02T08%3A00%3A00Z&limit=50", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"camera_id": 1,
"kind": "default",
"severity": "info",
"first": "2026-11-02T08:00:00Z",
"last": "2026-11-02T08:00:00Z",
"count": 12,
"event_id": "<event_id>",
"details": "<details>",
"state": "open",
"acked_by": "<acked_by>",
"acked_by_name": "<acked_by_name>",
"acked": "2026-11-02T08:00:00Z",
"note": "<note>",
"footage": "<footage>",
"footage_state": "none"
}
],
"next_before": 12
}Peringatan Terbuka Per Lokasi Yang Terlihat
GET/alerts/summary
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/alerts/summary" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/alerts/summary",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/alerts/summary", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"open": 12,
"sites": [
{
"site_id": 1,
"open": 12
}
]
}Jenis Peringatan Produk
GET/alerts/kinds
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/alerts/kinds" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/alerts/kinds",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/alerts/kinds", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": "<id>",
"severity": "info",
"window_s": 60
}
]
}Satu Peringatan
GET/alerts/{id}
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read. Tanpa personal_data jawabannya berbentuk anonim: tanpa nama, nomor polisi, gambar atau rekaman.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/alerts/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/alerts/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/alerts/1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"camera_id": 1,
"kind": "default",
"severity": "info",
"first": "2026-11-02T08:00:00Z",
"last": "2026-11-02T08:00:00Z",
"count": 12,
"event_id": "<event_id>",
"details": "<details>",
"state": "open",
"acked_by": "<acked_by>",
"acked_by_name": "<acked_by_name>",
"acked": "2026-11-02T08:00:00Z",
"note": "<note>",
"footage": "<footage>",
"footage_state": "none"
}Tandai Peringatan Sudah Ditangani, Dengan Catatan Opsional (Dicatat Di Log Audit)
POST/alerts/{id}/ack
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
note | string |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/alerts/1/ack" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"note":"<note>"}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/alerts/1/ack",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"note": "<note>"
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/alerts/1/ack", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"note": "<note>"
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"camera_id": 1,
"kind": "default",
"severity": "info",
"first": "2026-11-02T08:00:00Z",
"last": "2026-11-02T08:00:00Z",
"count": 12,
"event_id": "<event_id>",
"details": "<details>",
"state": "open",
"acked_by": "<acked_by>",
"acked_by_name": "<acked_by_name>",
"acked": "2026-11-02T08:00:00Z",
"note": "<note>",
"footage": "<footage>",
"footage_state": "none"
}Kontak Dan Notifikasi
Siapa yang diberi tahu tentang peringatan, dan log pesan yang dikirim kepada mereka.
Kontak Peringatan Lokasi
GET/sites/{id}/contacts
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: read, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1/contacts" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1/contacts",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/contacts", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": true
}
]
}Tambahkan Kontak Peringatan
POST/sites/{id}/contacts
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
namewajib | string | |
email | string | |
whatsapp | string | E.164, misalnya +6281234567890 |
telegram | string | id chat Telegram |
language | enum | en, id |
channels | enum[] | |
kinds | string[] | jenis peringatan; [] = semua jenis |
min_severity | enum | info, warning, critical |
quiet_start | string | |
quiet_end | string | |
active | boolean |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/sites/1/contacts" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","email":"ops@example.com","whatsapp":"<whatsapp>","telegram":"<telegram>","language":"en","channels":["email"],"kinds":["default"],"min_severity":"info","quiet_start":"08:00","quiet_end":"08:00","active":true}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/sites/1/contacts",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/contacts", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": true
}),
});
console.log(r.status, await r.text());Respons 201
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": true
}Ubah Kontak Peringatan
PATCH/contacts/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
name | string | |
email | string | |
whatsapp | string | E.164, misalnya +6281234567890 |
telegram | string | id chat Telegram |
language | enum | en, id |
channels | enum[] | |
kinds | string[] | jenis peringatan; [] = semua jenis |
min_severity | enum | info, warning, critical |
quiet_start | string | |
quiet_end | string | |
active | boolean |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/contacts/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","email":"ops@example.com","whatsapp":"<whatsapp>","telegram":"<telegram>","language":"en","channels":["email"],"kinds":["default"],"min_severity":"info","quiet_start":"08:00","quiet_end":"08:00","active":true}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/contacts/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/contacts/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": true
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"email": "ops@example.com",
"whatsapp": "<whatsapp>",
"telegram": "<telegram>",
"language": "en",
"channels": [
"email"
],
"kinds": [
"default"
],
"min_severity": "info",
"quiet_start": "08:00",
"quiet_end": "08:00",
"active": true
}Hapus Kontak Peringatan
DELETE/contacts/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/contacts/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/contacts/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/contacts/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Pengiriman, Terbaru Lebih Dulu
GET/notify/deliveries
Siapa yang dapat memanggil: Akun yang menjadi Admin di suatu lokasi; jawabannya mencakup lokasi tersebut. Cakupan token: read, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
site query | integer | hanya lokasi ini |
ref query | string | misalnya alert:12 |
state query | string | queued, sending, sent atau failed |
before query | integer | next_before dari halaman sebelumnya |
limit query | integer | 1..500, bawaan 50 |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/notify/deliveries?site=1&before=2026-11-02T08%3A00%3A00Z&limit=50" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/notify/deliveries?site=1&before=2026-11-02T08%3A00%3A00Z&limit=50",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/notify/deliveries?site=1&before=2026-11-02T08%3A00%3A00Z&limit=50", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"ref": "<ref>",
"channel": "email",
"recipient": "<recipient>",
"state": "queued",
"attempts": 12,
"created": "2026-11-02T08:00:00Z",
"next": "2026-11-02T08:00:00Z",
"sent": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}
],
"next_before": 12
}Antrekan Lagi Pengiriman Yang Gagal (Masa Coba Ulang Baru)
POST/notify/deliveries/{id}/retry
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write, personal_data.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/notify/deliveries/1/retry" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/notify/deliveries/1/retry",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/notify/deliveries/1/retry", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"ref": "<ref>",
"channel": "email",
"recipient": "<recipient>",
"state": "queued",
"attempts": 12,
"created": "2026-11-02T08:00:00Z",
"next": "2026-11-02T08:00:00Z",
"sent": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}Webhook
Kiriman HTTP bertanda tangan berisi peringatan ke sistem lain (Standard Webhooks).
Webhook Lokasi
GET/sites/{id}/webhooks
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1/webhooks" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1/webhooks",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/webhooks", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": true,
"created": "2026-11-02T08:00:00Z"
}
]
}Tambahkan Webhook (Rahasianya Hanya Ada Di Jawaban Ini)
POST/sites/{id}/webhooks
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
namewajib | string | |
urlwajib | string | http(s); alamat internal ditolak |
kinds | string[] | jenis peringatan; [] = semua jenis |
active | boolean |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/sites/1/webhooks" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","url":"https://<RECEIVER_HOST>/hooks/arsa","kinds":["default"],"active":true}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/sites/1/webhooks",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/webhooks", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": true
}),
});
console.log(r.status, await r.text());Respons 201
{
"webhook": {
"id": 1,
"site_id": 1,
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": true,
"created": "2026-11-02T08:00:00Z"
},
"secret": "<WEBHOOK_SECRET>"
}Ubah Webhook
PATCH/webhooks/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
name | string | |
url | string | http(s); alamat internal ditolak |
kinds | string[] | jenis peringatan; [] = semua jenis |
active | boolean |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/webhooks/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","url":"https://<RECEIVER_HOST>/hooks/arsa","kinds":["default"],"active":true}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/webhooks/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhooks/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": true
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"kinds": [
"default"
],
"active": true,
"created": "2026-11-02T08:00:00Z"
}Hapus Webhook
DELETE/webhooks/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Selesai |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/webhooks/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/webhooks/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhooks/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Rahasia Baru (Rahasia Lama Langsung Berhenti Berlaku)
POST/webhooks/{id}/secret
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/webhooks/1/secret" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/webhooks/1/secret",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhooks/1/secret", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"secret": "<WEBHOOK_SECRET>"
}Kirim Peristiwa Uji Sekarang Dan Laporkan Hasilnya
POST/webhooks/{id}/test
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/webhooks/1/test" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/webhooks/1/test",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhooks/1/test", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"ok": true,
"error": "Text",
"retryable": true
}Webhook Untuk Integrator
Langganan milik akun API: peristiwa deteksi dalam batch, ringkasan berkala dan peringatan, ditandatangani, dengan log pengiriman.
Jenis Peristiwa Produk Untuk Langganan Webhook, Beserta Batasnya
GET/webhook-event-types
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/webhook-event-types" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/webhook-event-types",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-event-types", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"product": "traffic",
"items": [
{
"id": "traffic.passage",
"label": {
"en": "Vehicle passages",
"id": "Lintasan kendaraan"
},
"personal": [
"plate",
"photo"
],
"personal_admin": false,
"personal_only": false
},
{
"id": "traffic.speeding",
"label": {
"en": "Speeding",
"id": "Melaju terlalu cepat"
},
"personal": [
"plate"
],
"personal_admin": false,
"personal_only": false
}
],
"summaries": true,
"periods": [
"15m",
"1h",
"1d"
],
"batch_seconds": {
"min": 1,
"max": 3600,
"default": 10
},
"batch_max": {
"min": 1,
"max": 1000,
"default": 100
},
"max_per_account": 10
}Langganan Webhook Milik Akun API Pemilik Token
GET/webhook-subscriptions
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
account query | integer | hanya milik akun API ini |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/webhook-subscriptions?account=1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/webhook-subscriptions?account=1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions?account=1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"account_id": 1,
"account": "erp-sync",
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"<event_type>"
],
"sites": [
12
],
"batch_seconds": 60,
"batch_max": 12,
"summary": "15m",
"alerts": true,
"active": true,
"created": "2026-11-02T08:00:00Z",
"created_by": "<created_by>",
"health": {
"state": "ok",
"last_success": "2026-11-02T08:00:00Z",
"last_failure": "2026-11-02T08:00:00Z",
"last_error": "<last_error>",
"dropped": 12,
"queued": 12
},
"version": 3
}
]
}Daftarkan Akun API (Rahasianya Hanya Ada Di Jawaban Ini)
POST/webhook-subscriptions
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: write.
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
account_id | integer | akun API; untuk token: akunnya sendiri (boleh dihilangkan) |
namewajib | string | |
urlwajib | string | http(s); jaringan privat hanya bila perangkat mengizinkannya |
event_types | string[] | jenis peristiwa produk yang aktif (GET /webhook-event-types) |
sites | integer[] | id lokasi di dalam lokasi milik akun; [] = semua lokasi akun |
batch_seconds | integer | bawaan 10 saat dibuat |
batch_max | integer | bawaan 100 saat dibuat |
summary | enum | ringkasan berkala angka ikhtisar per lokasi, di zona waktu lokasi; null: tanpa ringkasan 15m, 1h, 1d, null |
alerts | boolean | bawaan false saat dibuat |
active | boolean | bawaan true saat dibuat |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
409 | Konflik |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/webhook-subscriptions" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"ERP receiver","url":"https://<RECEIVER_HOST>/hooks/arsa","event_types":["traffic.passage","traffic.speeding"],"sites":[1],"summary":"1h","alerts":true}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/webhook-subscriptions",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "ERP receiver",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"traffic.passage",
"traffic.speeding"
],
"sites": [
1
],
"summary": "1h",
"alerts": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "ERP receiver",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"traffic.passage",
"traffic.speeding"
],
"sites": [
1
],
"summary": "1h",
"alerts": true
}),
});
console.log(r.status, await r.text());Respons 201
{
"subscription": {
"id": 5,
"account_id": 2,
"account": "erp-sync",
"name": "ERP receiver",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"traffic.passage",
"traffic.speeding"
],
"sites": [
1
],
"batch_seconds": 10,
"batch_max": 100,
"summary": "1h",
"alerts": true,
"active": true,
"created": "2026-11-06T03:00:00Z",
"created_by": "api:erp-sync",
"health": {
"state": "ok",
"last_success": null,
"last_failure": null,
"last_error": null,
"dropped": 0,
"queued": 0
},
"version": 1
},
"secret": "<WEBHOOK_SECRET>"
}Satu Langganan Webhook Beserta Kesehatannya
GET/webhook-subscriptions/{id}
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/webhook-subscriptions/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/webhook-subscriptions/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions/1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"account_id": 1,
"account": "erp-sync",
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"<event_type>"
],
"sites": [
12
],
"batch_seconds": 60,
"batch_max": 12,
"summary": "15m",
"alerts": true,
"active": true,
"created": "2026-11-02T08:00:00Z",
"created_by": "<created_by>",
"health": {
"state": "ok",
"last_success": "2026-11-02T08:00:00Z",
"last_failure": "2026-11-02T08:00:00Z",
"last_error": "<last_error>",
"dropped": 12,
"queued": 12
},
"version": 3
}Ubah Langganan Webhook (Jeda, Atau Lanjutkan Mulai Saat Ini)
PATCH/webhook-subscriptions/{id}
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
account_id | integer | tidak dapat diubah |
name | string | |
url | string | http(s); jaringan privat hanya bila perangkat mengizinkannya |
event_types | string[] | jenis peristiwa produk yang aktif (GET /webhook-event-types) |
sites | integer[] | id lokasi di dalam lokasi milik akun; [] = semua lokasi akun |
batch_seconds | integer | bawaan 10 saat dibuat |
batch_max | integer | bawaan 100 saat dibuat |
summary | enum | ringkasan berkala angka ikhtisar per lokasi, di zona waktu lokasi; null: tanpa ringkasan 15m, 1h, 1d, null |
alerts | boolean | bawaan false saat dibuat |
active | boolean | bawaan true saat dibuat |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/webhook-subscriptions/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"account_id":1,"name":"Main gate","url":"https://<RECEIVER_HOST>/hooks/arsa","event_types":["<event_type>"],"sites":[12],"batch_seconds":60,"batch_max":12,"summary":"15m","alerts":true,"active":true}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/webhook-subscriptions/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"account_id": 1,
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"<event_type>"
],
"sites": [
12
],
"batch_seconds": 60,
"batch_max": 12,
"summary": "15m",
"alerts": True,
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"account_id": 1,
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"<event_type>"
],
"sites": [
12
],
"batch_seconds": 60,
"batch_max": 12,
"summary": "15m",
"alerts": true,
"active": true
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"account_id": 1,
"account": "erp-sync",
"name": "Main gate",
"url": "https://<RECEIVER_HOST>/hooks/arsa",
"event_types": [
"<event_type>"
],
"sites": [
12
],
"batch_seconds": 60,
"batch_max": 12,
"summary": "15m",
"alerts": true,
"active": true,
"created": "2026-11-02T08:00:00Z",
"created_by": "<created_by>",
"health": {
"state": "ok",
"last_success": "2026-11-02T08:00:00Z",
"last_failure": "2026-11-02T08:00:00Z",
"last_error": "<last_error>",
"dropped": 12,
"queued": 12
},
"version": 3
}Hapus Langganan Webhook Beserta Log Pengirimannya
DELETE/webhook-subscriptions/{id}
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/webhook-subscriptions/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/webhook-subscriptions/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Rahasia Penandatanganan Baru (Yang Lama Langsung Berhenti Berlaku); Hanya Ada Di Jawaban Ini
POST/webhook-subscriptions/{id}/secret
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/webhook-subscriptions/1/secret" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/webhook-subscriptions/1/secret",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions/1/secret", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"secret": "<WEBHOOK_SECRET>"
}Kirim Pesan Uji Bertanda Tangan Sekarang Dan Laporkan Hasilnya (Disimpan Di Log Pengiriman Sebagai Uji)
POST/webhook-subscriptions/{id}/test
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/webhook-subscriptions/1/test" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/webhook-subscriptions/1/test",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions/1/test", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"ok": true,
"error": "Text",
"retryable": true
}Log Pengiriman Langganan, Terbaru Lebih Dulu
GET/webhook-subscriptions/{id}/deliveries
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
state query | enum | queued, sending, sent, failed, dropped |
before query | integer | next_before dari halaman sebelumnya |
limit query | integer | 1..500, bawaan 50 |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/webhook-subscriptions/1/deliveries?state=queued&before=2026-11-02T08%3A00%3A00Z&limit=50" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/webhook-subscriptions/1/deliveries?state=queued&before=2026-11-02T08%3A00%3A00Z&limit=50",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-subscriptions/1/deliveries?state=queued&before=2026-11-02T08%3A00%3A00Z&limit=50", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"subscription_id": 1,
"kind": "events",
"site_id": 1,
"count": 12,
"bytes": 12,
"webhook_id": "<webhook_id>",
"state": "queued",
"attempts": 12,
"status": 12,
"created": "2026-11-02T08:00:00Z",
"next": "2026-11-02T08:00:00Z",
"expires": "2026-11-02T08:00:00Z",
"sent": "2026-11-02T08:00:00Z",
"last_error": "<last_error>",
"retryable": true
}
],
"next_before": 12
}Kirim Lagi Sekarang Pengiriman Yang Gagal Atau Menunggu, Dengan Masa 24 Jam Baru
POST/webhook-deliveries/{id}/retry
Siapa yang dapat memanggil: Akun API pemilik langganan tersebut (dengan tokennya sendiri). Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/webhook-deliveries/1/retry" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/webhook-deliveries/1/retry",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/webhook-deliveries/1/retry", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"subscription_id": 1,
"kind": "events",
"site_id": 1,
"count": 12,
"bytes": 12,
"webhook_id": "<webhook_id>",
"state": "queued",
"attempts": 12,
"status": 12,
"created": "2026-11-02T08:00:00Z",
"next": "2026-11-02T08:00:00Z",
"expires": "2026-11-02T08:00:00Z",
"sent": "2026-11-02T08:00:00Z",
"last_error": "<last_error>",
"retryable": true
}Sirene Dan Relai
Keluaran yang dinyalakan oleh peringatan: papan Modbus TCP, relai dan sirene HTTP, keluaran alarm ONVIF.
Keluaran Sirene Dan Relai Lokasi, Beserta Statusnya
GET/sites/{id}/relays
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1/relays" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1/relays",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/relays", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": true,
"password_set": true,
"state": {
"on": true,
"since": "2026-11-02T08:00:00Z",
"until": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}
}
]
}Tambahkan Keluaran (Papan Modbus TCP, Relai Atau Sirene HTTP, Keluaran Alarm Kamera ONVIF)
POST/sites/{id}/relays
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
namewajib | string | |
kindwajib | enum | modbus, http, onvif |
settingswajib | object | per jenis. modbus: host, port (502), unit (1), coil, invert. http: on_url, off_url, method (GET|POST|PUT), username. onvif: device_url, relay_token, username. |
kinds | string[] | |
cameras | integer[] | |
min_severity | enum | info, warning, critical |
mode | enum | pulse, until_ack |
pulse_s | integer | |
active | boolean | |
password | string |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/sites/1/relays" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","kind":"modbus","settings":{},"kinds":["default"],"cameras":[12],"min_severity":"info","mode":"pulse","pulse_s":60,"active":true,"password":"<password>"}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/sites/1/relays",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": True,
"password": "<password>"
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/relays", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": true,
"password": "<password>"
}),
});
console.log(r.status, await r.text());Respons 201
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": true,
"password_set": true,
"state": {
"on": true,
"since": "2026-11-02T08:00:00Z",
"until": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}
}Ubah Keluaran (Dijeda Saat Menyala: Dimatikan)
PATCH/relays/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
name | string | |
kind | enum | modbus, http, onvif |
settings | object | per jenis. modbus: host, port (502), unit (1), coil, invert. http: on_url, off_url, method (GET|POST|PUT), username. onvif: device_url, relay_token, username. |
kinds | string[] | |
cameras | integer[] | |
min_severity | enum | info, warning, critical |
mode | enum | pulse, until_ack |
pulse_s | integer | |
active | boolean | |
password | string | tidak ada: tetap; kosong: dihapus |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/relays/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Main gate","kind":"modbus","settings":{},"kinds":["default"],"cameras":[12],"min_severity":"info","mode":"pulse","pulse_s":60,"active":true,"password":"<password>"}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/relays/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": True,
"password": "<password>"
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/relays/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": true,
"password": "<password>"
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": true,
"password_set": true,
"state": {
"on": true,
"since": "2026-11-02T08:00:00Z",
"until": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}
}Hapus Keluaran (Dimatikan Lebih Dulu)
DELETE/relays/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/relays/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/relays/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/relays/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Pulsa Uji 2 Detik Sekarang; Melaporkan Apakah Perangkat Menyala
POST/relays/{id}/test
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/relays/1/test" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/relays/1/test",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/relays/1/test", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"ok": true,
"error": "Text"
}Matikan Keluaran Sekarang (Hentikan Sirene)
POST/relays/{id}/off
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
409 | Konflik |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/relays/1/off" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/relays/1/off",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/relays/1/off", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"name": "Main gate",
"kind": "modbus",
"settings": {},
"kinds": [
"default"
],
"cameras": [
12
],
"min_severity": "info",
"mode": "pulse",
"pulse_s": 60,
"active": true,
"password_set": true,
"state": {
"on": true,
"since": "2026-11-02T08:00:00Z",
"until": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}
}50 Peralihan Terakhir, Terbaru Lebih Dulu
GET/relays/{id}/events
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/relays/1/events" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/relays/1/events",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/relays/1/events", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"at": "2026-11-02T08:00:00Z",
"action": "on",
"cause": "alert",
"alert_id": 1,
"ok": true,
"error": "Text"
}
]
}Laporan
Laporan PDF dan XLSX yang dibuat sekarang atau terjadwal.
Laporan Yang Tersedia Di Dasbor Ini
GET/reports/kinds
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/reports/kinds" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/reports/kinds",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/reports/kinds", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": "<id>",
"title": {
"en": "<en>",
"id": "<id>"
}
}
]
}File Laporan Lokasi, Terbaru Lebih Dulu (Disimpan 90 Hari)
GET/sites/{id}/reports
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
limit query | integer | 1..500, bawaan 100 |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1/reports?limit=50" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1/reports?limit=50",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/reports?limit=50", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"report": "<report>",
"title": "Weekly summary",
"period": "1h",
"language": "en",
"format": "pdf",
"bytes": 12,
"created": "2026-11-02T08:00:00Z",
"created_by": "<created_by>",
"schedule_id": 1,
"download": "<download>"
}
]
}Buat Laporan Sekarang Untuk Tanggal Lokal Di Zona Waktu Lokasi (Paling Lama 366 Hari)
POST/sites/{id}/reports
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
reportwajib | string | |
fromwajib | date | |
towajib | date | |
language | enum | en, id |
formats | enum[] |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/sites/1/reports" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"report":"<report>","from":"2026-11-02","to":"2026-11-02","language":"en","formats":["pdf"]}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/sites/1/reports",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"report": "<report>",
"from": "2026-11-02",
"to": "2026-11-02",
"language": "en",
"formats": [
"pdf"
]
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/reports", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"report": "<report>",
"from": "2026-11-02",
"to": "2026-11-02",
"language": "en",
"formats": [
"pdf"
]
}),
});
console.log(r.status, await r.text());Respons 201
{
"items": [
{
"id": 1,
"site_id": 1,
"report": "<report>",
"title": "Weekly summary",
"period": "1h",
"language": "en",
"format": "pdf",
"bytes": 12,
"created": "2026-11-02T08:00:00Z",
"created_by": "<created_by>",
"schedule_id": 1,
"download": "<download>"
}
]
}Unduh File Laporan
GET/reports/files/{id}
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read, export.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | File |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/reports/files/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/reports/files/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/reports/files/1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Hapus File Laporan
DELETE/reports/files/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/reports/files/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/reports/files/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/reports/files/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Laporan Terjadwal Lokasi
GET/sites/{id}/report-schedules
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/sites/1/report-schedules" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/sites/1/report-schedules",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/report-schedules", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": 1,
"site_id": 1,
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": true,
"next_run": "2026-11-02T08:00:00Z",
"last_run": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}
]
}Jadwalkan Laporan (Dikirim Lewat E-Mail Ke Kontak Yang Dipilih Dalam Bahasa Mereka)
POST/sites/{id}/report-schedules
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
reportwajib | string | |
periodwajib | enum | daily: hari sebelumnya; weekly (setiap Senin): Senin sampai Minggu sebelumnya; monthly (tanggal 1): bulan sebelumnya daily, weekly, monthly |
hour | integer | jam lokal pengiriman |
recipients | integer[] | id kontak lokasi (kontak dengan alamat e-mail menerimanya, dalam bahasa mereka) |
formats | enum[] | |
active | boolean |
Respons
| Status | Arti |
|---|---|
201 | Dibuat |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/sites/1/report-schedules" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"report":"<report>","period":"daily","hour":7,"recipients":[12],"formats":["pdf"],"active":true}'import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/sites/1/report-schedules",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/sites/1/report-schedules", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": true
}),
});
console.log(r.status, await r.text());Respons 201
{
"id": 1,
"site_id": 1,
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": true,
"next_run": "2026-11-02T08:00:00Z",
"last_run": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}Ubah Jadwal (Waktu Jatuh Tempo Berikutnya Menyesuaikan)
PATCH/report-schedules/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
report | string | |
period | enum | daily: hari sebelumnya; weekly (setiap Senin): Senin sampai Minggu sebelumnya; monthly (tanggal 1): bulan sebelumnya daily, weekly, monthly |
hour | integer | jam lokal pengiriman |
recipients | integer[] | id kontak lokasi (kontak dengan alamat e-mail menerimanya, dalam bahasa mereka) |
formats | enum[] | |
active | boolean |
Respons
| Status | Arti |
|---|---|
200 | OK |
400 | Permintaan tidak valid |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
413 | Isi permintaan terlalu besar |
415 | Bukan JSON |
422 | Isi permintaan tidak valid |
Permintaan
curl -s -X PATCH "https://<BOX_HOST>/api/v1/report-schedules/1" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"report":"<report>","period":"daily","hour":7,"recipients":[12],"formats":["pdf"],"active":true}'import requests
r = requests.patch(
"https://<BOX_HOST>/api/v1/report-schedules/1",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": True
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/report-schedules/1", {
method: "PATCH",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": true
}),
});
console.log(r.status, await r.text());Respons 200
{
"id": 1,
"site_id": 1,
"report": "<report>",
"period": "daily",
"hour": 7,
"recipients": [
12
],
"formats": [
"pdf"
],
"active": true,
"next_run": "2026-11-02T08:00:00Z",
"last_run": "2026-11-02T08:00:00Z",
"last_error": "<last_error>"
}Hapus Jadwal
DELETE/report-schedules/{id}
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
204 | Dihapus |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X DELETE "https://<BOX_HOST>/api/v1/report-schedules/1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.delete(
"https://<BOX_HOST>/api/v1/report-schedules/1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/report-schedules/1", {
method: "DELETE",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Kirim Sekarang Untuk Periode Lengkap Terakhir
POST/report-schedules/{id}/run
Siapa yang dapat memanggil: Akun yang menjadi Admin di lokasi tersebut. Cakupan token: write.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
503 | Mesin analitik tidak menjawab (engine_unavailable); coba lagi setelah Retry-After |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/v1/report-schedules/1/run" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/v1/report-schedules/1/run",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/report-schedules/1/run", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"files": [
12
],
"queued": 12
}Sistem
Apakah dasbor sedang berjalan.
Apakah Dasbor Sedang Berjalan
GET/health
Siapa yang dapat memanggil: Tanpa autentikasi.
Respons
| Status | Arti |
|---|---|
200 | OK |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/health"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/health",
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/health", {
method: "GET",
});
console.log(r.status, await r.text());Respons 200
{
"status": "ok"
}Sertifikat TLS Dasbor Sebagai PEM (box.pem), Agar Klien Dapat Memverifikasi Sambungan
GET/system/certificate
Sertifikat perangkat sebagai berkas PEM (box.pem), hanya sertifikatnya, tidak pernah kuncinya; header X-Certificate-SHA256 memuat sidik jarinya. Sertifikat ini bersifat publik, sehingga token akun API mana pun dengan read dapat mengambilnya. Bandingkan sidik jarinya dengan sidik jari yang dibaca Admin di dasbor sebelum klien Anda memercayai berkas itu. Menjawab 404 dengan kode certificate_not_available jika dasbor diakses melalui proxy yang memegang sertifikatnya.
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | Rantai sertifikat, hanya sertifikatnya (tidak pernah kuncinya); sidik jarinya juga ada di X-Certificate-SHA256 |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
404 | Tidak ditemukan (juga bila akun tidak memiliki peran di lokasi tersebut) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/system/certificate" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/system/certificate",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/system/certificate", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Apakah Dasbor Memiliki Sertifikat Untuk Diunduh, Sidik Jari SHA-256-nya Dan Nama Yang Dicakupnya
GET/system/certificate/info
Apakah perangkat memiliki sertifikat untuk diberikan, asalnya, sidik jari SHA-256-nya (angka yang dibandingkan dengan yang terlihat oleh klien Anda) dan nama yang dicakupnya: nama host dan alamat yang dapat dipakai klien Anda untuk tersambung.
Siapa yang dapat memanggil: Setiap akun API. Cakupan token: read.
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Tidak terautentikasi: token tidak ada, salah, dicabut atau kedaluwarsa (token_invalid) |
403 | Dilarang: akun tidak memiliki peran untuk ini, tidak memiliki cakupan (scope_required), atau panggilan ini ditolak untuk token API (api_account_refused) |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/v1/system/certificate/info" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/v1/system/certificate/info",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/v1/system/certificate/info", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"available": true,
"filename": "box.pem",
"source": "self-signed",
"sha256": "3A:1F:00:7C:AA:42:9B:10:5E:61:D3:0C:88:24:F7:93:2B:6E:C1:58:04:9A:7D:E2:13:B5:66:0F:4C:D8:A1:39",
"certificates": 1,
"names": [
"<BOX_HOST>",
"<BOX_HOST>.local",
"localhost",
"::1",
"<BOX_LAN_ADDRESS>"
]
}