Dokumentasi / AI Box Dan Software Analitik Video / Referensi API
API Smart Retail Counter
API Smart Retail Counter: lalu lintas toko dari kamera pintu dan lantai. API ini memberikan jumlah pengunjung masuk, orang yang lewat dan tingkat tangkap, kunjungan dan waktu tinggal per zona, peta panas waktu tinggal (per zona dan jam, serta di lantai setiap kamera), panjang antrean dan waktu tunggu terukur, log pengunjung, dan transaksi kasir (POS) toko untuk tingkat konversi. API ini juga mengatur garis pintu dan garis staf kamera.
Data pribadi. Penghitungan bersifat anonim: API tidak memberikan identitas maupun gambar.
Memanggil API
Sama seperti API platform: token akun API sebagai Authorization: Bearer <API_KEY>. Id lokasi dan kamera berasal dari API platform (GET /api/v1/sites, GET /api/v1/cameras). Setiap operasi menyebutkan siapa yang dapat memanggilnya dan cakupan yang diperlukan. Galat, waktu, halaman dan batas laju mengikuti API platform.
Umpan dengan Kredensialnya Sendiri
Kasir toko dapat mengirim transaksinya sendiri, ditandatangani dengan kunci POS lokasi (tanda tangan Standard Webhooks); Admin lokasi membuat kunci tersebut di dasbor.
1.0.0
Lalu Lintas Toko
Angka utama, tren, zona, peta panas zona dan lantai, serta antrean.
Angka Utama Suatu Periode
GET/sites/{id}/overview
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/overview?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/overview?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/overview?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"entries": 1284,
"exits": 1241,
"passersby": 5310,
"capture_rate": 19.5,
"visits": 1190,
"engaged_rate": 41.3,
"checkout_rate": 28.7,
"avg_dwell_min": 11.4,
"conversion": {
"value": 24.1,
"source": "pos",
"transactions": 309
},
"in_store_now": 37,
"queues_now": [
{
"zone": "Checkout",
"length": 4,
"est_wait_s": 95,
"at": "2026-11-02T10:58:00Z",
"long_queue_length": 6
}
],
"repeat_share": null,
"vip_visits": 0,
"demographics": {
"cells": [
{
"age_band": "25-34",
"gender": "female",
"visits": 214,
"share": 22.3
}
],
"unknown_visits": 231
},
"occupancy_limit": 120,
"long_queue_length": 6,
"store_hours": {
"open": "10:00",
"close": "22:00"
}
}Pengunjung Masuk, Orang Yang Lewat Dan Kunjungan Per Jam Atau Hari
GET/sites/{id}/trend
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time | |
bucket query | enum | hour, day |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/trend?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&bucket=hour" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/trend?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&bucket=hour",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/trend?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&bucket=hour", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"bucket": "hour",
"buckets": [
{
"start": "2026-11-02T08:00:00Z",
"entries": 12,
"passersby": 12,
"visits": 12,
"engaged": 12,
"checkout": 12,
"capture_rate": 12
}
]
}Kunjungan Dan Waktu Tinggal Per Zona
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 | |
fromwajib query | date-time | |
towajib query | date-time |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/zones?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/zones?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/zones?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"zones": [
{
"zone": "Loading bay",
"kind": "default",
"visits": 12,
"avg_dwell_s": 60,
"total_dwell_min": 12
}
]
}Menit Waktu Tinggal Per Zona Dan Jam Lokal
GET/sites/{id}/heatmap
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/heatmap?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/heatmap?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/heatmap?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"zones": [
"Loading bay"
],
"hours": 12,
"dwell_min": [
[
12
]
]
}Peta Panas Lantai Satu Kamera: Detik Per Sel Grid Di Area Lantainya
GET/sites/{id}/floor-heatmap
Kamera lokasi yang memiliki area lantai (masih di lokasi) dan, untuk camera (jika tidak, yang pertama), area lantainya sesuai laporan terakhir: ukuran grid, poligon (koordinat bingkai ternormalisasi) dan detik pembeli berdiri di setiap sel, dijumlahkan selama jam-jam yang beririsan dengan periode (seconds[row][col], 0 bila tidak ada; sel kotak grid di luar poligon tetap 0). Anonim: tanpa jejak, tanpa gambar. floor bernilai null bila tidak ada kamera di lokasi yang memiliki area lantai. 404 floor_not_found: kamera tidak memiliki area lantai di lokasi ini.
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time | |
camera query | integer | Kamera (salah satu dari cameras); bawaan: yang pertama |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/floor-heatmap?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&camera=1" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/floor-heatmap?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&camera=1",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/floor-heatmap?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&camera=1", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"cameras": [
{
"camera": 12,
"zone": "Loading bay",
"name": "Main gate"
}
],
"floor": {
"camera": 12,
"zone": "Loading bay",
"name": "Main gate",
"cols": 12,
"rows": 12,
"polygon": [
[
12,
12
]
],
"seconds": [
[
12
]
],
"total_s": 60,
"max_s": 60,
"last_report": "2026-11-02T08:00:00Z"
}
}Panjang Antrean Dan Waktu Tunggu Terukur Per Jam Atau Hari
GET/sites/{id}/queues
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time | |
bucket query | enum | hour, day |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/queues?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&bucket=hour" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/queues?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&bucket=hour",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/queues?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&bucket=hour", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"bucket": "hour",
"samples": [
{
"start": "2026-11-02T08:00:00Z",
"zone": "Loading bay",
"avg_length": 12,
"max_length": 12,
"avg_wait_s": 60
}
]
}Seberapa Sering Kunjungan Diikuti Lintas Kamera, Per Jam Dan Totalnya
GET/sites/{id}/journey-stats
Kunjungan diikuti lintas kamera toko berdasarkan penampilan pembeli: kamera pintu membukanya, jejak di kamera tanpa pintu bergabung bila tampak seperti pembeli yang sama, dan pintu menutupnya (atau kunjungan berakhir 20 menit setelah terakhir terlihat). Angka ini menunjukkan seberapa sering penggabungan itu terjadi: joined_share adalah porsi jejak di kamera tanpa pintu yang bergabung dengan suatu kunjungan; sisanya menjadi kunjungan tersendiri yang hanya terlihat di dalam. Dihitung per jam UTC. Anonim: hanya hitungan.
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/journey-stats?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/journey-stats?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/journey-stats?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"from": "2026-11-02T08:00:00Z",
"to": "2026-11-02T08:00:00Z",
"totals": {
"opened": 12,
"joined": 12,
"unjoined": 12,
"closed_door": 12,
"timed_out": 12
},
"joined_share": 12,
"hours": [
{
"start": "2026-11-02T08:00:00Z",
"opened": 12,
"joined": 12,
"unjoined": 12,
"closed_door": 12,
"timed_out": 12,
"joined_share": 12
}
]
}Log Pengunjung
Setiap kunjungan, terbaru lebih dulu, dan ekspornya.
Log Pengunjung, Terbaru Lebih Dulu, Per Halaman
GET/sites/{id}/logs
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time | |
limit query | integer | |
before query | string |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/logs?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&limit=50&before=2026-11-02T08%3A00%3A00Z" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/logs?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&limit=50&before=2026-11-02T08%3A00%3A00Z",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/logs?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&limit=50&before=2026-11-02T08%3A00%3A00Z", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"items": [
{
"id": "31:7712",
"entered": "2026-11-02T10:31:02Z",
"exited": "2026-11-02T10:44:40Z",
"dwell_s": 818,
"engaged": true,
"reached_checkout": true,
"age_band": "25-34",
"gender": "female",
"repeat_visitor": null,
"entry_line": "Main door",
"cameras": [
31,
32
],
"zones": [
{
"zone": "Aisle 2",
"kind": "display",
"dwell_s": 240
}
],
"path": [
{
"camera": 31,
"camera_name": "Main door",
"entered": "2026-11-02T10:31:02Z",
"dwell_s": 95,
"zones": []
},
{
"camera": 32,
"camera_name": "Aisles",
"entered": "2026-11-02T10:32:37Z",
"dwell_s": 723,
"zones": [
{
"zone": "Aisle 2",
"kind": "display",
"entered": "2026-11-02T10:35:10Z",
"dwell_s": 240
}
]
}
]
}
],
"next_before": "2026-11-02T10:31:02Z"
}Log Pengunjung Suatu Periode Sebagai CSV Atau XLSX (Waktu Di Zona Waktu Lokasi, Paling Banyak 20 000 Baris; Kolom Jalur Mencantumkan Kamera Setiap Kunjungan Secara Berurutan, Beserta Zonanya)
GET/sites/{id}/logs/export
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read, export.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time | |
format query | enum | csv, xlsx |
language query | enum | en, id |
Respons
| Status | Arti |
|---|---|
200 | file |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/logs/export?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&format=csv&language=en" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/logs/export?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&format=csv&language=en",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/logs/export?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00&format=csv&language=en", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Kasir (POS)
Transaksi dari kasir (POS) toko (umpan bertanda tangan atau CSV) untuk tingkat konversi.
Unggah Transaksi POS Sebagai CSV (start,end,transactions)
POST/sites/{id}/pos/upload
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 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/retail/v1/sites/1/pos/upload" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.post(
"https://<BOX_HOST>/api/retail/v1/sites/1/pos/upload",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/pos/upload", {
method: "POST",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"stored": 12
}Interval POS Lokasi Dalam Suatu Periode, Dan Apakah Lokasi Memiliki Kunci
GET/sites/{id}/pos
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
fromwajib query | date-time | |
towajib query | date-time |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/pos?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/pos?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/pos?from=2026-11-01T00%3A00%3A00%2B07%3A00&to=2026-11-02T00%3A00%3A00%2B07%3A00", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"key": true,
"intervals": [
{
"start": "2026-11-02T08:00:00Z",
"end": "2026-11-02T08:00:00Z",
"transactions": 12,
"source": "pos"
}
]
}Transaksi POS Yang Dikirim Oleh Kasir Toko, Ditandatangani Dengan Kunci Lokasi
POST/pos/{site}
Kasir menandatangani isi permintaan dengan kunci POS lokasi dengan cara Standard Webhooks: webhook-id, webhook-timestamp (dalam 5 menit) dan webhook-signature. Stempel waktu yang selisihnya lebih dari 5 menit, id pesan yang berulang atau tanda tangan yang salah ditolak. Satu interval disimpan sekali per lokasi dan waktu mulai: laporan berikutnya untuk interval yang sama menggantikannya.
Autentikasi: Kunci kasir (POS) lokasi (dibuat oleh Admin lokasi di dasbor); tanpa token API.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
sitewajib path | integer | |
webhook-idwajib header | string | Id unik untuk pesan ini, paling banyak 128 karakter. Id yang berulang ditolak. |
webhook-timestampwajib header | string | Waktu penandatanganan dalam detik Unix; harus dalam 5 menit dari jam perangkat. |
webhook-signaturewajib header | string | v1, diikuti HMAC-SHA256 dalam base64 atas <webhook-id>.<webhook-timestamp>.<body> dengan kunci lokasi (bagian base64 setelah whsec_). Beberapa tanda tangan boleh diberikan, dipisahkan spasi. |
Body
| Kolom | Tipe | Deskripsi |
|---|---|---|
intervalswajib | object[] | |
intervals[].startwajib | date-time | |
intervals[].endwajib | date-time | |
intervals[].transactionswajib | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X POST "https://<BOX_HOST>/api/retail/v1/pos/1" \
-H "webhook-id: <WEBHOOK_ID>" \
-H "webhook-timestamp: <WEBHOOK_TIMESTAMP>" \
-H "webhook-signature: <WEBHOOK_SIGNATURE>" \
-H "Content-Type: application/json" \
-d '{"intervals":[{"start":"2026-11-02T10:00:00+07:00","end":"2026-11-02T11:00:00+07:00","transactions":42}]}'import requests
r = requests.post(
"https://<BOX_HOST>/api/retail/v1/pos/1",
headers={"webhook-id": "<WEBHOOK_ID>", "webhook-timestamp": "<WEBHOOK_TIMESTAMP>", "webhook-signature": "<WEBHOOK_SIGNATURE>"},
json={
"intervals": [
{
"start": "2026-11-02T10:00:00+07:00",
"end": "2026-11-02T11:00:00+07:00",
"transactions": 42
}
]
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/pos/1", {
method: "POST",
headers: { "webhook-id": "<WEBHOOK_ID>", "webhook-timestamp": "<WEBHOOK_TIMESTAMP>", "webhook-signature": "<WEBHOOK_SIGNATURE>", "Content-Type": "application/json" },
body: JSON.stringify({
"intervals": [
{
"start": "2026-11-02T10:00:00+07:00",
"end": "2026-11-02T11:00:00+07:00",
"transactions": 42
}
]
}),
});
console.log(r.status, await r.text());Respons 200
{
"stored": 12
}Pengaturan
Jam buka, batas okupansi, aturan antrean dan kunjungan, retensi, garis pintu dan garis staf setiap kamera, serta lintasan pintu terbarunya (uji garis pintu).
Pengaturan Smart Retail Counter Di Lokasi
GET/sites/{id}/settings
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 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/sites/1/settings" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/sites/1/settings",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/settings", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"engaged_min_s": 60,
"long_queue_length": 12,
"occupancy_limit": 12,
"open": "08:00",
"close": "08:00",
"stats_days": 30,
"identity_days": 12,
"version": 3,
"visit_timeout_s": 60
}Ubah Pengaturan Smart Retail Counter Di Lokasi (Diterapkan Ke Setiap Kamera Di Lokasi)
PUT/sites/{id}/settings
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 |
|---|---|---|
engaged_min_swajib | number | |
long_queue_lengthwajib | integer | Jumlah orang di zona antrean yang memicu retail.long_queue; zona antrean boleh menetapkan nilainya sendiri (long_queue_length pada zona di geometri kamera), ini nilai bawaannya |
occupancy_limit | integer | |
openwajib | string | |
closewajib | string | |
stats_dayswajib | integer | |
identity_dayswajib | integer | |
version | integer | |
visit_timeout_s | integer |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X PUT "https://<BOX_HOST>/api/retail/v1/sites/1/settings" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"engaged_min_s":60,"long_queue_length":12,"occupancy_limit":12,"open":"08:00","close":"08:00","stats_days":30,"identity_days":12,"version":3,"visit_timeout_s":60}'import requests
r = requests.put(
"https://<BOX_HOST>/api/retail/v1/sites/1/settings",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"engaged_min_s": 60,
"long_queue_length": 12,
"occupancy_limit": 12,
"open": "08:00",
"close": "08:00",
"stats_days": 30,
"identity_days": 12,
"version": 3,
"visit_timeout_s": 60
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/sites/1/settings", {
method: "PUT",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"engaged_min_s": 60,
"long_queue_length": 12,
"occupancy_limit": 12,
"open": "08:00",
"close": "08:00",
"stats_days": 30,
"identity_days": 12,
"version": 3,
"visit_timeout_s": 60
}),
});
console.log(r.status, await r.text());Respons 200
{
"engaged_min_s": 60,
"long_queue_length": 12,
"occupancy_limit": 12,
"open": "08:00",
"close": "08:00",
"stats_days": 30,
"identity_days": 12,
"version": 3,
"visit_timeout_s": 60
}Garis Pintu Dan Garis Staf Kamera
GET/cameras/{id}/lines
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 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/cameras/1/lines" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/cameras/1/lines",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/cameras/1/lines", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"camera": 12,
"door_lines": [
"<door_line>"
],
"staff_lines": [
"<staff_line>"
],
"default": "<default>"
}Atur Garis Pintu Dan Garis Staf Kamera (ID Garis Di Geometri)
PUT/cameras/{id}/lines
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 |
|---|---|---|
door_lines | string[] | |
staff_lines | string[] |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
422 | Problem RFC 9457 |
502 | Problem RFC 9457 |
Permintaan
curl -s -X PUT "https://<BOX_HOST>/api/retail/v1/cameras/1/lines" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"door_lines":["<door_line>"],"staff_lines":["<staff_line>"]}'import requests
r = requests.put(
"https://<BOX_HOST>/api/retail/v1/cameras/1/lines",
headers={"Authorization": "Bearer <API_KEY>"},
json={
"door_lines": [
"<door_line>"
],
"staff_lines": [
"<staff_line>"
]
},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/cameras/1/lines", {
method: "PUT",
headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" },
body: JSON.stringify({
"door_lines": [
"<door_line>"
],
"staff_lines": [
"<staff_line>"
]
}),
});
console.log(r.status, await r.text());Respons 200
{
"camera": 12,
"door_lines": [
"<door_line>"
],
"staff_lines": [
"<staff_line>"
]
}Lintasan Pintu Terbaru Kamera (Uji Garis Pintu)
GET/cameras/{id}/crossings
Lintasan pintu yang dilaporkan untuk kamera setelah after, terlama lebih dulu, paling banyak 500 per panggilan; garis pintu dapat diperiksa langsung dengannya. Tanpa after: tanpa lintasan, hanya kursor untuk memulai. Anonim: tanpa jejak atau identitas.
Siapa yang dapat memanggil: Akun dengan peran (Pemantau atau Admin) di lokasi tersebut. Cakupan token: read.
Parameter
| Kolom | Tipe | Deskripsi |
|---|---|---|
idwajib path | integer | |
after query | integer | cursor dari panggilan sebelumnya |
Respons
| Status | Arti |
|---|---|
200 | OK |
401 | Problem RFC 9457 |
403 | Problem RFC 9457 |
404 | Problem RFC 9457 |
409 | Problem RFC 9457 |
Permintaan
curl -s -X GET "https://<BOX_HOST>/api/retail/v1/cameras/1/crossings?after=2026-11-02T08%3A00%3A00Z" \
-H "Authorization: Bearer <API_KEY>"import requests
r = requests.get(
"https://<BOX_HOST>/api/retail/v1/cameras/1/crossings?after=2026-11-02T08%3A00%3A00Z",
headers={"Authorization": "Bearer <API_KEY>"},
)
print(r.status_code, r.text)const r = await fetch("https://<BOX_HOST>/api/retail/v1/cameras/1/crossings?after=2026-11-02T08%3A00%3A00Z", {
method: "GET",
headers: { "Authorization": "Bearer <API_KEY>" },
});
console.log(r.status, await r.text());Respons 200
{
"camera": 12,
"cursor": 12,
"crossings": [
{
"line": "<line>",
"direction": "in",
"staff": true,
"time": "2026-11-02T08:00:00Z"
}
]
}