Skip to content

Instantly share code, notes, and snippets.

@splch
Created March 15, 2026 14:36
Show Gist options
  • Select an option

  • Save splch/52b7abae6102f2dfb21ab2a18225fc2c to your computer and use it in GitHub Desktop.

Select an option

Save splch/52b7abae6102f2dfb21ab2a18225fc2c to your computer and use it in GitHub Desktop.
Avycon AVR-NSV08P8 NVR HTTP API — OpenAPI 3.1.0 spec (reverse-engineered from live device)
openapi: 3.1.0
info:
title: Avycon NVR HTTP API
description: |
Reverse-engineered API specification for the Avycon AVR-NSV08P8 Diversity Series
8-Channel 4K NVR with 8 PoE ports.
Firmware: V8.2.3.2-20230816 | Web Client: V1.3.1.7 | HTTP API: V1.026
## Authentication Flow
1. `POST /API/Login/Range` - Get login parameters (no auth required)
2. `POST /API/Login/TransKey/Get` - Get encryption key (HTTP Digest auth required)
3. `POST /API/Web/Login` - Authenticate (HTTP Digest auth required)
- Response returns `X-csrftoken` header and `Set-Cookie: session=...`
4. All subsequent requests use session cookie + CSRF token
## Request/Response Convention
All POST endpoints accept and return JSON with this envelope:
**Request:** `{"version": "1.0", "data": { ... }}`
**Success:** `{"result": "success", "data": { ... }}`
**Error:** `{"result": "failed", "reason": "...", "error_code": "...", "data": { ... }}`
## CRUD Convention
Most configuration endpoints support four operations via URL suffix:
- `/Get` - Read current values
- `/Set` - Write new values
- `/Range` - Get validation schema (allowed values, min/max)
- `/Default` - Get factory default values
Some endpoints support additional operations:
`/Search`, `/Check`, `/Test`, `/Format`, `/Format/Progress`,
`/Token`, `/Upgrade`, `/Import`, `/Export`, `/Delete`,
`/Play`, `/Scan`, `/Join`, `/Control`, `/GetId`
## Request Conventions for Config Endpoints
- AlarmConfig/* and AI/Setup/* endpoints require `page_type: "AlarmConfig"` and `channel: 0` (integer) in the request data
- PreviewChannel/PTZ/* endpoints require `channel: "CH1"` (string) in the request data
- Most config endpoints return a `channel_info` object keyed by channel name (CH1, CH2, etc.)
- Range responses include validation constraints (min/max/enum)
## Device Model Notes (AVR-NSV08P8)
The following endpoint groups are NOT supported by this device model and will return 404:
AlarmConfig/PIR, AlarmConfig/Sabotage, AlarmConfig/Thermal, AlarmConfig/EventPush,
AlarmConfig/RS485Alarm, AlarmConfig/Intelligent/FaceDisarm,
ChannelConfig/AntiFog, ChannelConfig/DIS, ChannelConfig/VideoCrop, ChannelConfig/ChannelConfig,
ChannelConfig/AutoAddIPC, ChannelConfig/RemoteDev,
StreamConfig/FourthStream,
NetworkConfig/P2P, NetworkConfig/Rtsp, NetworkConfig/APN, NetworkConfig/IEEE8021x,
NetworkConfig/MqttServerInfo, NetworkConfig/T28181, NetworkConfig/Tuya,
StorageConfig/Raid, StorageConfig/SharedCloud, StorageConfig/Server,
SystemConfig/AlarmOut, SystemConfig/Serail, SystemConfig/Zero,
AI/Setup/SOD, AI/Setup/FDD, AI/Setup/SVD, AI/Setup/OPD, AI/Setup/BBD,
AI/Setup/VQA, AI/Setup/LD, AI/Setup/BJJYAlarm, AI/Setup/Tracking,
Maintenance/FOTA, Maintenance/DefoggingFan, Maintenance/AutoUpgrade
version: 1.0.26
contact:
name: Avycon Support
url: https://www.avycon.com
servers:
- url: http://{host}:{port}
description: Avycon NVR (HTTP)
variables:
host:
default: 192.168.0.175
port:
default: "80"
- url: https://{host}:{port}
description: Avycon NVR (HTTPS - self-signed cert)
variables:
host:
default: 192.168.0.175
port:
default: "443"
tags:
- name: Authentication
description: Login, logout, session management, heartbeat
- name: System Info
description: Read-only device information
- name: System Config
description: General system settings (date/time, users, output)
- name: Network
description: Network configuration (TCP/IP, DDNS, email, FTP, SNMP, RTMP, ONVIF)
- name: Channel Config
description: IP camera channel management, OSD, image, PTZ
- name: Stream Config
description: Video stream encoding settings (main, sub, mobile)
- name: Record
description: Recording configuration and schedules
- name: Storage
description: Disk management, cloud storage
- name: Alarm
description: Alarm/event configuration (motion, I/O, intelligent, deterrence)
- name: AI
description: AI analytics setup and search (face, person/vehicle, LPR, heat map)
- name: Preview
description: Live preview, PTZ control, manual alarm, streaming
- name: Playback
description: Recording search, playback, download, snapshots
- name: Maintenance
description: Firmware upgrade, logs, reboot, factory reset, param backup
- name: Schedules
description: Time-based schedules for recording, alarm, FTP, email, etc.
- name: Events
description: Real-time event/alarm long-polling
security:
- sessionAuth: []
csrfToken: []
components:
securitySchemes:
digestAuth:
type: http
scheme: digest
description: |
HTTP Digest Authentication (RFC 7616).
realm="device", algorithm=SHA-256, qop="auth", userhash=true.
Used only for /API/Web/Login and /API/Login/TransKey/Get.
sessionAuth:
type: apiKey
in: cookie
name: session
description: Session cookie returned by /API/Web/Login
csrfToken:
type: apiKey
in: header
name: X-csrftoken
description: CSRF token returned in X-csrftoken response header from /API/Web/Login
schemas:
# ── Envelope ──────────────────────────────────────────────
ApiRequest:
type: object
required: [version, data]
properties:
version:
type: string
enum: ["1.0"]
data:
type: object
SuccessResponse:
type: object
properties:
result:
type: string
enum: [success]
data:
type: object
ErrorResponse:
type: object
properties:
result:
type: string
enum: [failed]
reason:
type: string
error_code:
type: string
enum:
- no_login
- expired
- one_IE
- no_permission
- param_error
- operation_failed
- not_found
- method_not_allowed
- login_failed_or_block
- device_reboot
- disk_changed
- passwd_expired
- network_changed
- frequent_operation
- uri_too_long
- http_redirect_https
- payload_too_large
- internal_server_error
- connect_server_timeout
- server_response_timeout
- user_expired
- no_heartbeat
- readerID_invalid
- position_invalid
- verify_failed
- login_block
- pwd_equal_name
- pwd_equal_name_no_reverse
- get_image_failed
- handle_processed
- fail_refresh
- fail_default
- no_support
data:
type: object
properties:
block_remain_time:
type: string
description: Seconds remaining on account lockout
login_remain_time:
type: string
restart_time:
type: integer
# ── Authentication ────────────────────────────────────────
LoginRangeResponse:
type: object
properties:
username:
type: object
properties:
type:
type: string
min_len:
type: integer
max_len:
type: integer
password:
type: object
properties:
type:
type: string
min_len:
type: integer
max_len:
type: integer
pwd_tip:
type: string
first_login_flag:
type: boolean
password_enc:
type: boolean
http_api_version:
type: string
example: V1.026
default_lang:
type: string
example: ENU
custom_name:
type: integer
custom_logo:
type: integer
login_exclusivity:
type: boolean
lang_strs:
type: object
additionalProperties:
type: string
example:
ENU: ENGLISH
KOR: KOREAN
support_recover_password:
type: boolean
use_recover_password:
type: boolean
site_version:
type: string
example: AVR-NSV08P8
LoginRequest:
type: object
properties:
version:
type: string
enum: ["1.0"]
data:
type: object
properties:
base_enc_password:
type: object
description: X25519-encrypted password (when password_enc=true)
properties:
seq:
type: integer
peer_key:
type: string
description: Client X25519 public key (base64)
cipher:
type: string
description: Encrypted password
base_secondary_authentication:
type: object
description: PBKDF2-SHA256 derived cipher (optional)
properties:
seq:
type: integer
cipher:
type: string
remote_terminal_info:
type: string
example: "WEB,chrome"
LoginResponse:
type: object
properties:
strength_need_check:
type: boolean
last_login_time:
type: string
last_login_ip:
type: string
pwd_remain_time:
type: string
fail_login_count:
type: string
user:
type: string
token:
type: string
TransKeyRequest:
type: object
properties:
version:
type: string
enum: ["1.0"]
data:
type: object
required: [type]
properties:
type:
type: array
items:
type: string
enum: [base_x_public, base_salt]
description: Request one type at a time
TransKeyResponse:
type: object
properties:
Key_lists:
type: array
items:
type: object
properties:
type:
type: string
enum: [base_x_public, base_salt]
key:
type: string
description: Base64-encoded key material
seq:
type: integer
iter:
type: integer
description: PBKDF2 iterations (base_salt only)
AccountRulesResponse:
type: object
properties:
username:
type: object
properties:
type:
type: string
min_len:
type: integer
max_len:
type: integer
password_modify_ipc:
type: object
properties:
type:
type: string
min_len:
type: integer
max_len:
type: integer
password:
type: object
properties:
type:
type: string
min_len:
type: integer
max_len:
type: integer
RecoverPasswordAuthResponse:
type: object
properties:
mode:
type: string
example: SuperPwd
system_time:
type: string
example: "03/15/2026 06:47:48"
mac_address:
type: string
example: "28-36-13-D1-25-50"
# ── Device Info ───────────────────────────────────────────
DeviceInfoResponse:
type: object
properties:
device_main_menu:
type: array
items:
type: string
example: [localSetting, remoteSetting, playback, preview]
intelligent_chn_arr:
type: array
items:
type: string
example: [CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH8]
channel_num:
type: integer
example: 8
analog_channel_num:
type: integer
sys_channel_num:
type: integer
stream_profile:
type: object
properties:
type:
type: string
items:
type: array
items:
type: string
example: [Mainstream, Substream, Mobilestream]
support_ftp_upgrade:
type: boolean
support_cloud_upgrade:
type: boolean
push_type:
type: string
default_stream:
type: string
pushinfo_type:
type: object
properties:
type:
type: string
items:
type: array
items:
type: string
local_alarmin_num:
type: integer
local_alarmout_num:
type: integer
mac_addr:
type: string
example: 28-36-13-D1-25-50
media_port:
type: integer
example: 9000
media_external_port:
type: integer
local_ip:
type: string
example: 192.168.0.175
enable_encryption:
type: boolean
device_type:
type: string
example: AVR-NSV08P8
dev_type:
type: integer
p2p_id:
type: string
example: GSZLRUDWAJUYT8HN111A
support_ai:
type: boolean
support_face_config:
type: boolean
support_face_attribute:
type: boolean
support_human_vehicle_search:
type: boolean
support_license_plate:
type: boolean
support_hls_server:
type: boolean
support_speaker:
type: boolean
support_smart_record:
type: boolean
support_substream_playback:
type: boolean
support_backward_play:
type: boolean
support_record_tag:
type: boolean
support_manual_record:
type: boolean
support_heat_map:
type: boolean
support_fisheye:
type: boolean
support_ai_pidlcd:
type: boolean
support_ai_cc:
type: boolean
support_disarming:
type: boolean
talkback:
type: string
enum: [TalkFull, TalkHalf, ""]
sound:
type: boolean
videoloss_status:
type: boolean
cast_screen_google_url:
type: string
cast_screen_aws_url:
type: string
device_preview_ability:
type: array
items:
type: string
device_preview_AI_item:
type: array
items:
type: string
example: [FR, Human, Vehicle, Non-Vehicle, PID_Human, PID_Vehicle, LCD_Human, LCD_Vehicle, LPR]
ChannelInfoResponse:
type: object
properties:
channel_param:
type: object
properties:
type:
type: string
min_size:
type: integer
max_size:
type: integer
items:
type: array
items:
$ref: "#/components/schemas/ChannelParam"
ChannelParam:
type: object
properties:
channel:
type: string
example: CH1
connect_status:
type: string
enum: [Online, Offline, FailConnectNetwork, NotConfigured]
channel_name:
type: string
example: Driveway
channel_alias:
type: string
ability:
type: array
items:
type: string
example: [Mainstream, Substream, Mobilestream, AudioAlarm, RedBlueLight, TalkFull, Color, Cover]
intelligent_ability:
type: array
items:
type: string
example: [CrossCount, HeatMap, SOD, LCD, PVD, FD, PID, CrowdDensity, LPD, RSD, QD, AttributeDetect]
alarm_in_num:
type: integer
alarm_out_num:
type: integer
videoloss:
type: boolean
# ── System Info ───────────────────────────────────────────
SystemInfoBase:
type: object
description: "Verified against live API: SystemInfo/Base/Get"
properties:
device_name:
type: string
example: AVR-NSV08P8
device_type:
type: string
example: AVR-NSV08P8
hardware_version:
type: string
example: DM-443
software_version:
type: string
example: V8.2.3.2-20230816
ie_client_version:
type: string
example: V1.3.1.7
video_format:
type: string
enum: [NTSC, PAL]
hdd_volume:
type: string
example: 5589G
ip_address:
type: string
ipv6_address:
type: string
web:
type: string
description: "Internal,external web port"
example: "80,80"
client:
type: string
description: "Internal,external client port"
example: "9000,9000"
mac_address:
type: string
example: 28-36-13-D1-25-50
p2p_id:
type: string
network_state:
type: string
example: Unconnected
iot_id:
type: string
language:
type: string
example: English
SystemInfoChannelResponse:
type: object
description: "Verified against live API: SystemInfo/Channel/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/SystemInfoChannelEntry"
channel_max:
type: integer
example: 8
SystemInfoChannelEntry:
type: object
properties:
alias:
type: string
example: CAM1
state:
type: string
enum: [Online, Offline]
mainstream:
type: string
example: "3840x2160, 25Fps, 5Mbps"
substream:
type: string
example: "640x480, 25Fps, 512Kbps"
mobile_stream:
type: string
example: "640x480, 25Fps, 512Kbps"
motion_detection:
type: string
enum: [Support, ""]
privacy_zone:
type: string
enum: [Support, ""]
SystemInfoRecordResponse:
type: object
description: "Verified against live API: SystemInfo/Record/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/SystemInfoRecordEntry"
channel_max:
type: integer
SystemInfoRecordEntry:
type: object
properties:
record_state:
type: string
enum: ["On", "Off"]
record_switch:
type: string
enum: [Enable, Disable]
stream_type:
type: string
example: DualStream
resolution:
type: string
example: "3840x2160 | 640x480"
fps:
type: string
example: "25Fps | 25Fps"
bitrate:
type: string
example: "5Mbps | 512Kbps"
SystemInfoNetworkResponse:
type: object
description: "Verified against live API: SystemInfo/Network/Get"
properties:
wan:
type: object
properties:
dhcp:
type: string
enum: [Enable, Disable]
ip_address:
type: string
subnet_mask:
type: string
gateway:
type: string
ipv6_address:
type: string
ipv6_gateway:
type: string
mac_address:
type: string
lan:
type: object
properties:
ip_address:
type: string
subnet_mask:
type: string
dns1:
type: string
dns2:
type: string
pppoe:
type: object
properties:
enable:
type: string
enum: [enable, disable]
port:
type: object
properties:
web:
type: string
example: "80,80,Inactive,Disable"
client:
type: string
example: "9000,9000,Inactive,Disable"
bandwidth:
type: object
properties:
total_bandwidth:
type: string
example: "131072Kbps"
used_bandwidth:
type: string
example: "18432Kbps"
# ── System Config ─────────────────────────────────────────
SystemGeneralConfig:
type: object
description: "Verified against live API: SystemConfig/General/Get"
properties:
device_name:
type: string
example: AVR-NSV08P8
menu_timeouts:
type: integer
description: "Allowed values: 0, 30, 60, 120, 300, 600 seconds"
example: 60
session_timeout:
type: integer
description: "Range: 5-1440 minutes"
example: 5
preview_session_timeout:
type: boolean
SystemDateTimeConfig:
type: object
description: "Verified against live API: SystemConfig/DateTime/Get"
properties:
date:
type: string
example: "03/15/2026"
time:
type: string
example: "06:47:24"
date_format:
type: string
enum: [MM/DD/YYYY, YYYY-MM-DD, DD/MM/YYYY]
time_format:
type: integer
enum: [12, 24]
time_zone:
type: string
example: "(GMT-8:00) Pacific Time(US and Canada)"
NTPConfig:
type: object
description: "Verified against live API: SystemConfig/NTP/Get"
properties:
ntp_enable:
type: boolean
server:
type: string
enum: [time.windows.com, time.nist.gov, pool.ntp.org, UserDefined]
custom_server:
type: string
DSTConfig:
type: object
description: "Verified against live API: SystemConfig/DST/Get"
properties:
dst_enable:
type: boolean
time_offset:
type: integer
enum: [1, 2]
dst_mode:
type: string
enum: [Week, Date]
start_month:
type: string
end_month:
type: string
start_week:
type: string
end_week:
type: string
start_weekday:
type: string
end_weekday:
type: string
start_date:
type: string
end_date:
type: string
start_hour:
type: string
end_hour:
type: string
support_crossyear:
type: boolean
OutputConfig:
type: object
description: "Verified against live API: SystemConfig/Output/Get"
properties:
output:
type: object
additionalProperties:
type: object
properties:
output_resolution:
type: string
example: "1280x1024"
UserConfig:
type: object
description: "Verified against live API: SystemConfig/User/Get"
properties:
user_info:
type: object
additionalProperties:
$ref: "#/components/schemas/UserEntry"
UserEntry:
type: object
properties:
user_enable:
type: boolean
username_enable:
type: boolean
username:
type: string
password_empty:
type: boolean
password_disable:
type: boolean
# ── Network ───────────────────────────────────────────────
NetworkBaseConfig:
type: object
description: "Verified against live API: NetworkConfig/NetBase/Get"
properties:
wan:
type: object
properties:
dhcp:
type: boolean
ip_address:
type: string
subnet_mask:
type: string
gateway:
type: string
ipv6_address:
type: string
ipv6_prefixlen:
type: integer
ipv6_gateway:
type: string
dns1:
type: string
dns2:
type: string
dhcp_enable:
type: boolean
lan:
type: object
properties:
poedhcp:
type: boolean
ip_address:
type: string
subnet_mask:
type: string
pppoe:
type: object
properties:
enable:
type: boolean
username:
type: string
pppoenewstruct:
type: boolean
password_empty:
type: boolean
dns2:
type: string
wifi:
type: object
properties:
enable:
type: boolean
ssid:
type: string
password_empty:
type: boolean
ip_address:
type: string
status:
type: string
enum: [Connected, Unconnected]
port:
type: array
items:
type: object
properties:
service:
type: string
enum: [Web, Client]
protocol:
type: string
internal_port:
type: integer
external_port:
type: integer
upnp_status:
type: string
enum: [Active, Inactive]
maping_strategy:
type: string
upnp:
type: boolean
p2p_switch:
type: boolean
extern_ip:
type: string
device_instruction:
type: string
web_compatibility_mode:
type: boolean
video_encrypt_transfer:
type: array
items:
type: string
forward_port:
type: boolean
rtsp_url:
type: string
description: RTSP URL template
DDNSConfig:
type: object
description: "Verified against live API: NetworkConfig/DDNS/Get"
properties:
ddns_enable:
type: boolean
server:
type: string
example: NO_IP
domain:
type: string
username:
type: string
password:
type: string
password_empty:
type: boolean
test_befault_save:
type: boolean
EmailConfig:
type: object
description: "Verified against live API: NetworkConfig/Email/Get"
properties:
email_enable:
type: boolean
encryption:
type: string
example: Auto
smtp_port:
type: integer
smtp_server:
type: string
username:
type: string
password:
type: string
password_empty:
type: boolean
sender:
type: string
recvemail:
type: object
properties:
recvemail_1:
type: string
recvemail_2:
type: string
recvemail_3:
type: string
interval_time:
type: integer
FTPConfig:
type: object
description: "Verified against live API: NetworkConfig/Ftp/Get"
properties:
ftp_enable:
type: boolean
server_ip:
type: string
port:
type: integer
username:
type: string
password:
type: string
password_empty:
type: boolean
picture_quality:
type: string
video_stream_type:
type: string
max_package_interval:
type: integer
directory_name:
type: string
IPFilterConfig:
type: object
description: "Verified against live API: NetworkConfig/IPFilter/Get"
properties:
enable:
type: boolean
choose:
type: string
enum: [Whitelist, Blacklist]
restricted_type:
type: string
enum: [Whitelist, Blacklist]
whitelist:
type: array
items:
type: string
blacklist:
type: array
items:
type: string
HTTPSConfig:
type: object
description: "Verified against live API: NetworkConfig/https/Get"
properties:
https_enable:
type: boolean
file_type:
type: string
example: Default
file_exist:
type: integer
SNMPConfig:
type: object
description: "Verified against live API: NetworkConfig/Snmp/Get"
properties:
snmp_enable:
type: boolean
snmp_versions:
type: string
example: V1
snmp_port:
type: integer
read_community:
type: string
write_community:
type: string
trap_ipaddr:
type: string
trap_port:
type: integer
authentication:
type: object
properties:
readonly_user:
$ref: "#/components/schemas/SNMPUser"
readwrite_user:
$ref: "#/components/schemas/SNMPUser"
SNMPUser:
type: object
properties:
username:
type: string
authentication_type:
type: string
enum: [MD5, SHA]
authentication_password:
type: string
authentication_password_empty:
type: boolean
encrypted_type:
type: string
example: CBC-DES
encrypted_password:
type: string
encrypted_password_empty:
type: boolean
RTMPConfig:
type: object
description: "Verified against live API: NetworkConfig/Rtmp/Get"
properties:
rtmp_enable:
type: boolean
server_ipaddr:
type: string
stream_type:
type: string
enum: [Mainstream, Substream]
rtmp_channel:
type: array
items:
type: string
OnvifConfig:
type: object
description: "Verified against live API: NetworkConfig/Onvif/Get"
properties:
enable:
type: boolean
authentication:
type: string
example: "Digest/WSSE"
protocol:
type: string
example: "HTTP/HTTPS"
username:
type: string
password:
type: string
password_empty:
type: boolean
# ── Channel Config ────────────────────────────────────────
IPChannelConfig:
type: object
description: "Verified against live API: ChannelConfig/IPChannel/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/IPChannelEntry"
IPChannelEntry:
type: object
properties:
state:
type: string
enum: [Online, Offline]
switch_mode:
type: string
enum: [AutoMode, ManualMode]
poe_mode:
type: string
enum: [Auto, "Off"]
ip_address:
type: string
main_url:
type: string
description: Custom RTSP main stream URL (ManualMode only)
sub_url:
type: string
description: Custom RTSP sub stream URL (ManualMode only)
subnet_mask:
type: string
gateway:
type: string
port:
type: integer
channel_num:
type: integer
channel_index:
type: integer
protocol:
type: string
enum: [AVYCON, ONVIF, RTSP]
connect_method:
type: string
enum: [General]
username:
type: string
password:
type: string
description: Always empty in GET responses
password_empty:
type: boolean
manufacturer:
type: string
example: AVYCON
device_type:
type: string
example: AVC-NCE81F28
mac_address:
type: string
software_version:
type: string
network_mode:
type: string
enum: [Dhcp, Static]
OSDConfig:
type: object
description: "Verified against live API: ChannelConfig/OSD/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/OSDChannelEntry"
OSDChannelEntry:
type: object
properties:
status:
type: string
enum: [Online, Offline]
channel_enable:
type: boolean
name:
type: object
properties:
show:
type: boolean
text:
type: string
example: Driveway
pos:
type: object
properties:
x:
type: integer
y:
type: integer
datetime:
type: object
properties:
show:
type: boolean
date_format:
type: string
time_format:
type: integer
pos:
type: object
properties:
x:
type: integer
y:
type: integer
refresh_rate:
type: string
example: "60Hz"
covert:
type: boolean
osd_invert:
type: boolean
ColorConfig:
type: object
description: "Verified against live API: ChannelConfig/Color/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/ColorChannelEntry"
ColorChannelEntry:
type: object
properties:
hue:
type: integer
example: 128
bright:
type: integer
example: 128
contrast:
type: integer
example: 128
saturation:
type: integer
example: 128
sharpness:
type: integer
example: 128
support_default:
type: boolean
ImageControlConfig:
type: object
description: "Verified against live API: ChannelConfig/ImageControl/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/ImageControlChannelEntry"
ImageControlChannelEntry:
type: object
properties:
support_default:
type: boolean
mirror_mode:
type: string
example: Close
corridor_mode:
type: string
example: Close
angle_rotation:
type: string
example: "0"
Daylight:
type: object
properties:
back_light:
type: string
denoising:
type: string
denoising_level:
type: integer
white_balance:
type: string
red_tuning:
type: integer
green_tuning:
type: integer
blue_tuning:
type: integer
exposure_mode:
type: string
shutter_limit:
type: string
wdr_hide_ai_area:
type: boolean
image_setting:
type: string
example: FullColorMode
FullColorMode:
type: object
properties:
white_light:
type: string
image_sensitivity:
type: integer
VideoCoverConfig:
type: object
description: "Verified against live API: ChannelConfig/VideoCover/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/VideoCoverChannelEntry"
VideoCoverChannelEntry:
type: object
properties:
privacy_zone_enable:
type: boolean
zone_info:
type: array
items:
type: object
properties:
zone_no:
type: integer
zone_enable:
type: boolean
rect:
$ref: "#/components/schemas/Rect"
Rect:
type: object
properties:
left:
type: integer
top:
type: integer
width:
type: integer
height:
type: integer
ROIConfig:
type: object
description: "Verified against live API: ChannelConfig/ROI/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/ROIChannelEntry"
ROIChannelEntry:
type: object
properties:
main_stream_info:
type: object
additionalProperties:
type: object
properties:
roi_switch:
type: boolean
roi_level:
type: string
main_non_roi_fps:
type: string
rect:
type: object
properties:
left:
type: integer
top:
type: integer
width:
type: integer
height:
type: integer
PTZConfig:
type: object
description: "Verified against live API: ChannelConfig/PTZ/Get - most channels return reason:Not support"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
reason:
type: string
description: "Typically 'Not support' or 'Not configured' for fixed cameras"
status:
type: string
PoePowerConfig:
type: object
description: "Verified against live API: ChannelConfig/PoePower/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
channel_current_power:
type: string
example: "5.23"
actual_power:
type: string
example: "14.07"
surplus_power:
type: string
example: "44.93"
channel_min_power:
type: string
example: "0"
channel_max_power:
type: string
example: "30"
ProtocolManageConfig:
type: object
description: "Verified against live API: ChannelConfig/ProtocolManage/Get"
properties:
protocol_info:
type: object
additionalProperties:
type: object
properties:
protocol_name:
type: string
example: "Custom 1"
custom_stream:
type: array
items:
type: object
properties:
stream_name:
type: string
enable:
type: boolean
type:
type: string
enum: [Rtsp]
port:
type: integer
source_path:
type: string
DefaultPasswordConfig:
type: object
description: "Verified against live API: ChannelConfig/DefaultPassword/Get"
properties:
protocol_info:
type: object
additionalProperties:
type: object
properties:
username:
type: string
password_empty:
type: boolean
AudioConfig:
type: object
description: "Verified against live API: DeviceConfig/Audio/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/AudioChannelEntry"
AudioChannelEntry:
type: object
properties:
copy_ch:
type: string
audio_enable:
type: boolean
audio_type:
type: string
example: G711U
in_volume:
type: integer
out_volume:
type: integer
# ── Stream Config ─────────────────────────────────────────
StreamConfig:
type: object
description: "Verified against live API: StreamConfig/MainStream|SubStream|MobileStream/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/StreamChannelEntry"
StreamChannelEntry:
type: object
properties:
rtsp_enable:
type: boolean
enable_stream:
type: boolean
description: Present on MobileStream only
stream_type:
type: string
enum: [Normal, Alarm]
video_encode_type:
type: string
enum: ["H.264", "H.264+", "H.265", "H.265+"]
resolution:
type: string
example: "3840 x 2160"
fps:
type: integer
example: 25
bitrate_control:
type: string
enum: [CBR, VBR]
video_quality:
type: string
enum: [Lowest, Lower, Low, Medium, High, Higher, Highest]
bitrate_mode:
type: string
enum: [Predefined, Custom]
bitrate:
type: integer
description: Bitrate in kbps
example: 5120
custom_bitrate:
type: integer
audio:
type: boolean
i_frame_interval:
type: integer
example: 60
etr:
type: boolean
description: Enhanced Triggered Recording enabled (MainStream only)
etr_stream_type:
type: string
etr_resolution:
type: string
etr_fps:
type: integer
etr_video_encode_type:
type: string
etr_bitrate_control:
type: string
etr_video_quality:
type: string
etr_bitrate_mode:
type: string
etr_bitrate:
type: integer
etr_custom_bitrate:
type: integer
etr_audio:
type: boolean
etr_i_frame_interval:
type: integer
copy_ch:
type: string
channel_type:
type: string
CaptureConfig:
type: object
description: "Verified against live API: StreamConfig/Capture/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/CaptureChannelEntry"
CaptureChannelEntry:
type: object
properties:
auto_capture:
type: boolean
normal_interval:
type: integer
example: 5
alarm_interval:
type: integer
example: 5
copy_ch:
type: string
# ── Record Config ─────────────────────────────────────────
RecordConfig:
type: object
description: "Verified against live API: RecordConfig/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/RecordChannelEntry"
RecordChannelEntry:
type: object
properties:
record_switch:
type: boolean
stream_mode:
type: string
enum: [DualStream, MainStream, SubStream]
prerecord:
type: boolean
anr:
type: boolean
description: Automatic Network Replenishment
copy_ch:
type: string
# ── Storage ───────────────────────────────────────────────
StorageDiskConfig:
type: object
description: "Verified against live API: StorageConfig/Disk/Get"
properties:
disk_info:
type: array
items:
$ref: "#/components/schemas/DiskInfo"
NasMaxCount:
type: integer
over_write:
type: string
enum: [Auto, "Off"]
hdd_format_type:
type: string
example: AllHddData
support_format:
type: boolean
DiskInfo:
type: object
properties:
id:
type: integer
display_id:
type: integer
model:
type: string
example: ST6000VX001-2BD186
serial_no:
type: string
example: ZCT0XJ1E
firmware:
type: string
device_type:
type: string
enum: [Normal, ReadOnly, Redundant]
status:
type: string
enum: [Normal, Full, Error, Unformatted]
total_size:
type: integer
description: Total size in MB
free_size:
type: integer
description: Free size in MB
total_time:
type: integer
description: Total recording time in minutes
free_time:
type: integer
format_enable:
type: boolean
delete_enable:
type: boolean
CloudStorageConfig:
type: object
description: "Verified against live API: StorageConfig/Cloud/Get"
properties:
cloud_storage:
type: boolean
cloud_type:
type: string
enum: [DROPBOX]
cloud_status:
type: string
example: Unactivated
total_size:
type: string
example: "0.00B"
used_size:
type: string
progress:
type: integer
cloud_over_write:
type: string
enum: [Auto, "Off"]
video_type:
type: string
enum: [MP4]
channel_info:
type: object
additionalProperties:
type: object
properties:
folder_name:
type: string
# ── Alarm Config ──────────────────────────────────────────
VoicePromptsTimePeriod:
type: object
properties:
start_hour:
type: integer
start_minute:
type: integer
start_second:
type: integer
end_hour:
type: integer
end_minute:
type: integer
end_second:
type: integer
AlarmActionFields:
type: object
description: Common alarm action fields shared across Motion, IO, Intelligent, AI alarm configs
properties:
buzzer:
type: string
description: "Buzzer duration in seconds (string)"
example: "0"
alarm_out:
type: array
items:
type: string
latch_time:
type: string
example: "10"
record_enable:
type: boolean
record_channel:
type: array
items:
type: string
post_recording:
type: string
example: "30"
show_message:
type: boolean
send_email:
type: boolean
full_screen:
type: boolean
ftp_picture_upload:
type: boolean
ftp_video_upload:
type: boolean
picture_to_cloud:
type: boolean
video_to_cloud:
type: boolean
voice_prompts_index:
type: array
items:
type: integer
voice_prompts_select:
type: array
items:
type: integer
voice_prompts_time:
type: array
items:
$ref: "#/components/schemas/VoicePromptsTimePeriod"
copy_ch:
type: string
MotionDetectionConfig:
type: object
description: "Verified against live API: AlarmConfig/Motion/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/AlarmActionFields"
IOAlarmConfig:
type: object
description: "Verified against live API: AlarmConfig/IO/Get - keyed by alarm input name (e.g. Local<-1)"
properties:
channel_info:
type: object
additionalProperties:
allOf:
- $ref: "#/components/schemas/AlarmActionFields"
- type: object
properties:
alarm_type:
type: string
enum: [NormallyOpen, NormallyClosed]
channel:
type: array
items:
type: string
IntelligentAlarmConfig:
type: object
description: "Verified against live API: AlarmConfig/Intelligent/PID|LCD|SOD|SoundDetection/Get. Channels that are not configured return {reason: Not configured}."
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/AlarmActionFields"
CombinationAlarmConfig:
type: object
description: "Verified against live API: AlarmConfig/Combination/Get"
properties:
channel_info:
type: object
additionalProperties:
allOf:
- $ref: "#/components/schemas/AlarmActionFields"
- type: object
properties:
enable_alarm:
type: string
enum: [Enable, Disable]
combination_configure:
type: array
items:
type: object
properties:
alarm_type:
type: string
example: AT_MOTION
alarm_source:
type: string
example: IP Camera
support_ipc_io:
type: boolean
ExceptionAlarmConfig:
type: object
description: "Verified against live API: AlarmConfig/Exception/Get"
properties:
exception_info:
type: object
additionalProperties:
type: object
properties:
switch:
type: boolean
buzzer:
type: string
alarm_out:
type: array
items:
type: string
latch_time:
type: string
show_message:
type: boolean
send_email:
type: boolean
voice_prompts_index:
type: array
items:
type: integer
voice_prompts_select:
type: array
items:
type: integer
voice_prompts_time:
type: array
items:
$ref: "#/components/schemas/VoicePromptsTimePeriod"
PTZLinkageConfig:
type: object
description: "Verified against live API: AlarmConfig/PTZLinkage/Get"
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/PTZLinkageChannelEntry"
PTZLinkageChannelEntry:
type: object
properties:
switch:
type: boolean
all_alarm:
type: object
properties:
motion:
type: boolean
io:
type: array
items:
type: string
linkage_sod:
type: boolean
linkage_cc:
type: boolean
linkage_sound:
type: boolean
linkage_vt:
type: boolean
linkage_fd:
type: boolean
linkage_ad:
type: boolean
linkage_cd:
type: boolean
linkage_qd:
type: boolean
linkage_lpd:
type: boolean
linkage_rsd:
type: boolean
linkage_lpr:
type: boolean
linkage_fr:
type: boolean
linkage_ai_pid:
type: boolean
linkage_ai_lcd:
type: boolean
linkage_ai_pdvd:
type: boolean
ptz_info:
type: array
items:
type: object
properties:
ptz_switch:
type: boolean
ptz_chn:
type: string
linkage_ptz_point_index:
type: integer
copy_ch:
type: string
VoicePromptsConfig:
type: object
description: "Verified against live API: AlarmConfig/VoicePrompts/Get"
properties:
info:
type: object
properties:
language:
type: string
example: ENGLISH
ipc_channel_info:
type: array
items:
type: integer
url:
type: string
audio_list:
type: array
items:
type: object
DisarmingConfig:
type: object
description: "Verified against live API: AlarmConfig/Disarming/Get"
properties:
disarming:
type: boolean
action:
type: object
properties:
buzzer:
type: boolean
alarm_out:
type: boolean
show_message:
type: boolean
send_email:
type: boolean
full_screen:
type: boolean
voice_prompts:
type: boolean
disarming_channel:
type: array
items:
type: string
channel_info:
type: object
additionalProperties:
type: object
properties:
disarming_schedule:
type: array
items:
$ref: "#/components/schemas/ScheduleWeekBlock"
# ── Schedule ──────────────────────────────────────────────
ScheduleWeekBlock:
type: object
properties:
schedule_type:
type: string
description: "e.g. Normal, Motion, IO, AlarmOut, Disarming, fd, pvd, pid, lcd, etc."
mutex_type:
type: array
items:
type: string
description: Mutually exclusive schedule types (AI schedules only)
week:
type: array
items:
type: object
properties:
day:
type: string
enum: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
time:
type: array
items:
type: integer
description: "48 half-hour slots (0 or 1). Index 0 = 00:00-00:30, index 47 = 23:30-24:00"
ScheduleConfig:
type: object
description: "Verified against live API: Schedules/Record|Alarm|Capture|Email|Ftp|AI|Intelligent/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
category:
type: array
items:
$ref: "#/components/schemas/ScheduleWeekBlock"
AIScheduleConfig:
type: object
description: "Verified against live API: AI/Setup/AISchedule/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
AI_Schedule:
type: boolean
category:
type: array
items:
$ref: "#/components/schemas/ScheduleWeekBlock"
# ── AI Setup ──────────────────────────────────────────────
AIAlarmSetupConfig:
type: object
description: "Verified against live API: AI/Setup/PID|LCD|PVD|CD|CrossCount|QD|RSD|LPD/Get. Uses same alarm action fields."
properties:
channel_info:
type: object
additionalProperties:
$ref: "#/components/schemas/AlarmActionFields"
AIHeatMapConfig:
type: object
description: "Verified against live API: AI/Setup/HeatMap/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
switch:
type: boolean
rule_info:
type: object
additionalProperties:
type: object
properties:
rule_switch:
type: boolean
rule_rect:
type: object
properties:
x1:
type: integer
y1:
type: integer
x2:
type: integer
y2:
type: integer
x3:
type: integer
y3:
type: integer
x4:
type: integer
y4:
type: integer
AIFaceDetectionConfig:
type: object
description: "Verified against live API: AI/Setup/FD/Get - returns empty object per channel if not configured"
properties:
channel_info:
type: object
additionalProperties:
type: object
AIModelConfig:
type: object
description: "Verified against live API: AI/Model/Get"
properties:
auto_select_enable:
type: boolean
rows:
type: array
items:
type: object
properties:
channel:
type: string
face_recognition:
type: string
face_detection:
type: string
enable_face_recognition:
type: boolean
AIAttributeDetectConfig:
type: object
description: "Verified against live API: AI/Alarm/AttributeDetect/Get"
properties:
channel_info:
type: object
additionalProperties:
allOf:
- $ref: "#/components/schemas/AlarmActionFields"
- type: object
properties:
alarm_type:
type: string
example: Close
AICCStatisticsConfig:
type: object
description: "Verified against live API: AI/CCStatistics/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
search_date:
type: string
report_type:
type: string
detection_type:
type: string
cross_type:
type: string
ai_cross_count:
type: boolean
AIFDAttendanceConfig:
type: object
description: "Verified against live API: AI/FDAttendance/Get"
properties:
fd_atd_info:
type: object
properties:
enable:
type: boolean
mode:
type: string
enum: [Month, Week]
mode_week:
type: string
mode_month_day:
type: string
send_email:
type: string
on_duty_time:
type: string
off_duty_time:
type: string
working_days:
type: array
items:
type: string
channel:
type: array
items:
type: string
group:
type: array
items:
type: string
AIHeatMapStatisticsConfig:
type: object
description: "Verified against live API: AI/HeatMapStatistics/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
properties:
date:
type: string
start_hour:
type: integer
end_hour:
type: integer
report_type:
type: string
detection_type:
type: string
heat_map_type:
type: integer
IntelligentAnalysisConfig:
type: object
description: "Verified against live API: Intelligent/IntelligentAnalysis/Get"
properties:
channel_info:
type: object
additionalProperties:
type: object
# ── Preview / PTZ ─────────────────────────────────────────
PreviewPTZGetResponse:
type: object
description: "Verified against live API: PreviewChannel/PTZ/Get. Requires channel:CH1 in request."
properties:
channel:
type: string
example: CH1
disable_ManualHumanTrace:
type: boolean
speed:
type: integer
example: 5
current_cruise_mode:
type: string
example: Mode_Default_Cruise
PTZControlRequest:
type: object
required: [channel, cmd]
properties:
channel:
type: string
description: "Channel name string e.g. CH1 (not integer)"
cmd:
type: string
enum:
- Ptz_Cmd_Up
- Ptz_Cmd_Down
- Ptz_Cmd_Left
- Ptz_Cmd_Right
- Ptz_Cmd_UpLeft
- Ptz_Cmd_UpRight
- Ptz_Cmd_DownLeft
- Ptz_Cmd_DownRight
- Ptz_Cmd_CircleCenter
- Ptz_Cmd_ZoomAdd
- Ptz_Cmd_ZoomMinus
- Ptz_Cmd_FocusAdd
- Ptz_Cmd_FocusMinus
- Ptz_Cmd_IrisAdd
- Ptz_Cmd_IrisMinus
- Ptz_Cmd_AddPreset
- Ptz_Cmd_CallPreset
- Ptz_Cmd_ClearPreset
- Ptz_Cmd_Cruise
- Ptz_Cmd_DefCruise_Start
- Ptz_Cmd_DefCruise_Stop
- Ptz_3DPosition
- Ptz_Ctrl
- Ptz_Param_AutoFocus
- Ptz_QuickUse_3DPosition
- Ptz_QuickUse_AutoFocus
- Ptz_QuickUse_AutoHumanTrace
- Ptz_QuickUse_ManualHumanTrace
- Ptz_QuickUse_LensReset
- Ptz_QuickUse_PtzReset
- Ptz_QuickUse_WatchMode
- Ptz_QuickUse_WatchModeStart
- Ptz_QuickUse_WatchModeStop
state:
type: string
enum: [Start, Stop]
speed:
type: integer
minimum: 1
maximum: 10
zoom_step:
type: integer
zoom_slider:
type: integer
focus_step:
type: integer
focus_slider:
type: integer
preset_point_no:
type: integer
preset_point_name:
type: string
preset_point_time:
type: integer
trace_number:
type: integer
trace_preset_point:
type: array
items:
type: integer
trace_interval:
type: integer
pattern_scan_number:
type: integer
line_scan_speed:
type: integer
watch_mode_time:
type: integer
watch_mode_mode:
type: string
watch_mode_num:
type: integer
x1:
type: integer
description: 3D position box (Ptz_3DPosition)
y1:
type: integer
x2:
type: integer
y2:
type: integer
# ── Playback Search ───────────────────────────────────────
SearchMonthRequest:
type: object
properties:
channel:
type: array
items:
type: integer
description: 0-based channel indices
stream_type:
type: string
enum: [Mainstream, Substream]
start_date:
type: string
format: date
example: "2026-03-01"
search_type:
type: string
SearchDayRequest:
type: object
properties:
channel:
type: array
items:
type: integer
start_date:
type: string
format: date
start_time:
type: string
example: "00:00:00"
end_date:
type: string
format: date
end_time:
type: string
example: "23:59:59"
record_type:
type: integer
description: Bitmask of record types (0xFFFFFFFF = all)
default: 4294967295
stream_mode:
type: string
enum: [Mainstream, Substream]
smart_region:
type: array
items:
type: object
enable_smart_search:
type: integer
enum: [0, 1]
SnapshotRangeResponse:
type: object
description: "Verified against live API: Snapshot/Range"
properties:
channel_info:
type: object
properties:
type:
type: string
min_size:
type: integer
max_size:
type: integer
items:
type: array
items:
type: object
properties:
channel:
type: string
snapshot_resolution:
type: object
properties:
description:
type: string
type:
type: string
items:
type: array
items:
type: string
SnapshotRequest:
type: object
properties:
channel:
type: integer
description: 0-based channel index
snapshot_resolution:
type: string
example: "1920x1080"
reset_session_timeout:
type: boolean
default: false
SnapshotResponse:
type: object
properties:
img_format:
type: string
example: image/jpeg
img_data:
type: string
format: byte
description: Base64-encoded JPEG image
# ── Event Long Polling ────────────────────────────────────
EventCheckRequest:
type: object
properties:
reader_id:
type: string
description: Cursor returned by server (empty on first call)
sequence:
type: integer
description: Sequence number returned by server
lap_number:
type: integer
description: Lap number returned by server
EventCheckResponse:
type: object
properties:
reader_id:
type: string
sequence:
type: integer
lap_number:
type: integer
heat_alarm:
description: Present on empty poll (no events)
# ── Maintenance ───────────────────────────────────────────
AutoRebootConfig:
type: object
description: "Verified against live API: Maintenance/AutoReboot/Get"
properties:
auto_reboot:
type: boolean
period_mode:
type: string
enum: [EveryDay, EveryWeek, EveryMonth]
week:
type: string
example: Sun
time:
type: string
example: "05:00"
DeveloperModeConfig:
type: object
description: "Verified against live API: Maintenance/DeveloperMode/Get"
properties:
telnet_switch:
type: boolean
export_disk_switch:
type: string
enable_export:
type: boolean
enable_delete:
type: boolean
FtpUpgradeConfig:
type: object
description: "Verified against live API: Maintenance/FtpUpgrade/Get"
properties:
ftp_addr:
type: string
ftp_port:
type: integer
username:
type: string
user_pwd_empty:
type: boolean
ftp_path:
type: string
check_for_updates:
type: boolean
online_upgrade:
type: boolean
ResetSettingsConfig:
type: object
description: "Verified against live API: Maintenance/ResetSettings/Get"
properties:
load_default_switch:
type: boolean
format_hdd_switch:
type: boolean
# ── Misc ──────────────────────────────────────────────────
DevicePageResponse:
type: object
description: "Verified against live API: Login/DevicePage/Get"
properties:
main:
type: array
items:
type: object
properties:
title:
type: string
sub:
type: array
items:
type: object
properties:
title:
type: string
pages:
type: array
items:
type: object
properties:
title:
type: string
page:
type: string
RecordTypeBitmask:
type: integer
description: |
Bitfield of record types:
- 0x00000001: Normal
- 0x00000002: Alarm
- 0x00000004: Motion
- 0x00000008: I/O
- 0x00000010: Line Crossing (PEA)
- 0x00000020: AVD
- 0x00000040: Object Scene Change
- 0x00000200: Intrusion (PEA Area)
- 0x00000400: Occlusion
- 0x00000800: Network Break
- 0x00001000: Human/Vehicle Detection
- 0x00002000: Face Detection
- 0x00004000: People Counting
- 0x00010000: PIR
- 0x00020000: Sound
- 0x00040000: Manual
- 0x00080000: Smart
- 0x00100000: Occlusion Detection
- 0x00200000: Person Alarm
- 0x00400000: Face Attribute
- 0x00800000: CD
- 0x01000000: QD
- 0x02000000: License Plate (LPD)
- 0x04000000: RSD
- 0x08000000: ANR
- 0xFFFFFFFF: All types
StreamTypeEnum:
type: integer
enum: [0, 1, 2, 4, 6]
description: |
0=Mainstream, 1=Substream, 2=Mobilestream, 4=Zerostream, 6=Fourthstream
# ── Reusable request body ─────────────────────────────────
requestBodies:
EmptyApiRequest:
required: true
content:
application/json:
schema:
type: object
properties:
version:
type: string
enum: ["1.0"]
data:
type: object
default: {}
AlarmConfigRequest:
required: true
content:
application/json:
schema:
type: object
properties:
version:
type: string
enum: ["1.0"]
data:
type: object
properties:
page_type:
type: string
enum: [AlarmConfig]
channel:
type: integer
description: "0-based channel index"
default: 0
PTZChannelRequest:
required: true
content:
application/json:
schema:
type: object
properties:
version:
type: string
enum: ["1.0"]
data:
type: object
properties:
channel:
type: string
description: "Channel name string e.g. CH1"
example: CH1
paths:
# ════════════════════════════════════════════════════════════
# AUTHENTICATION
# ════════════════════════════════════════════════════════════
/API/Login/Range:
post:
operationId: getLoginRange
tags: [Authentication]
summary: Get login parameters and device identity
description: No authentication required. Returns password rules, language options, and device model.
security: []
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Login parameters
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/LoginRangeResponse"
/API/Login/TransKey/Get:
post:
operationId: getTransKey
tags: [Authentication]
summary: Get encryption key for password exchange
description: Requires HTTP Digest auth. Returns X25519 public key or PBKDF2 salt.
security:
- digestAuth: []
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/TransKeyRequest"
responses:
"200":
description: Encryption key material
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/TransKeyResponse"
/API/Web/Login:
post:
operationId: login
tags: [Authentication]
summary: Authenticate and create session
description: |
Requires HTTP Digest auth. On success, returns session cookie and CSRF token
in response headers. Use these for all subsequent requests.
security:
- digestAuth: []
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LoginRequest"
responses:
"200":
description: Login successful
headers:
Set-Cookie:
schema:
type: string
description: "session={token};HttpOnly;path=/"
X-csrftoken:
schema:
type: string
description: CSRF token for subsequent requests
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/LoginResponse"
"400":
description: Login failed or account locked
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/API/Web/Logout:
post:
operationId: logout
tags: [Authentication]
summary: End session
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Logged out
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Login/Heartbeat:
post:
operationId: heartbeat
tags: [Authentication]
summary: Keep session alive
description: "Must be sent periodically to prevent session timeout. Verified: returns empty data on success."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Session refreshed
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Login/DeviceInfo/Get:
post:
operationId: getDeviceInfo
tags: [Authentication]
summary: Get device capabilities and features
description: Returns channel count, AI capabilities, supported features, media port, P2P ID, etc.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Device capabilities
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DeviceInfoResponse"
/API/Login/ChannelInfo/Get:
post:
operationId: getChannelInfo
tags: [Authentication]
summary: Get channel status and capabilities
description: Returns per-channel online status, names, abilities, and intelligent abilities.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Channel information
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ChannelInfoResponse"
/API/Login/Password/Set:
post:
operationId: changePassword
tags: [Authentication]
summary: Change user password
description: Requires secondary authentication (PBKDF2) for the old password.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Password changed
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AccountRules/Get:
post:
operationId: getAccountRules
tags: [Authentication]
summary: Get password and username validation rules
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Validation rules
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AccountRulesResponse"
/API/RecoverPassword/Get:
post:
operationId: getRecoverPassword
tags: [Authentication]
summary: Get password recovery settings
description: "Verified: returns empty data object."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Password recovery config
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/RecoverPassword/Authorization/Get:
post:
operationId: getRecoverPasswordAuth
tags: [Authentication]
summary: Get password recovery authorization info
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Recovery authorization
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/RecoverPasswordAuthResponse"
/API/RecoverPassword/Certificate/Export:
post:
operationId: exportRecoveryCert
tags: [Authentication]
summary: Export password recovery certificate
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Recovery certificate
content:
application/octet-stream:
schema:
type: string
format: binary
# ════════════════════════════════════════════════════════════
# SYSTEM INFO (read-only)
# ════════════════════════════════════════════════════════════
/API/SystemInfo/Base/Get:
post:
operationId: getSystemInfoBase
tags: [System Info]
summary: Get device identity and version info
description: Returns model, hardware/software version, MAC, IP, HDD volume, P2P ID.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: System base info
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SystemInfoBase"
/API/SystemInfo/Channel/Get:
post:
operationId: getSystemInfoChannel
tags: [System Info]
summary: Get per-channel hardware info
description: "Verified: returns channel_info with alias, state, mainstream/substream/mobile_stream specs, motion_detection, privacy_zone support."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Channel hardware info
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SystemInfoChannelResponse"
/API/SystemInfo/Record/Get:
post:
operationId: getSystemInfoRecord
tags: [System Info]
summary: Get recording status info
description: "Verified: returns channel_info with record_state, record_switch, stream_type, resolution, fps, bitrate per channel."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Recording status
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SystemInfoRecordResponse"
/API/SystemInfo/Network/Get:
post:
operationId: getSystemInfoNetwork
tags: [System Info]
summary: Get network status info
description: "Verified: returns WAN/LAN info, DNS, PPPoE status, port info, bandwidth usage."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Network status
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SystemInfoNetworkResponse"
# ════════════════════════════════════════════════════════════
# SYSTEM CONFIG
# ════════════════════════════════════════════════════════════
/API/SystemConfig/General/Get:
post:
operationId: getSystemGeneral
tags: [System Config]
summary: Get general system settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: General settings
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SystemGeneralConfig"
/API/SystemConfig/General/Set:
post:
operationId: setSystemGeneral
tags: [System Config]
summary: Update general system settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/SystemGeneralConfig"
responses:
"200":
description: Settings updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/SystemConfig/DateTime/Get:
post:
operationId: getDateTime
tags: [System Config]
summary: Get date/time settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Date/time settings
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SystemDateTimeConfig"
/API/SystemConfig/DateTime/Set:
post:
operationId: setDateTime
tags: [System Config]
summary: Update date/time settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/SystemDateTimeConfig"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/SystemConfig/NTP/Get:
post:
operationId: getNTP
tags: [System Config]
summary: Get NTP settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: NTP config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/NTPConfig"
/API/SystemConfig/NTP/Set:
post:
operationId: setNTP
tags: [System Config]
summary: Update NTP settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/NTPConfig"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/SystemConfig/DST/Get:
post:
operationId: getDST
tags: [System Config]
summary: Get daylight saving time settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: DST config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DSTConfig"
/API/SystemConfig/Output/Get:
post:
operationId: getOutputConfig
tags: [System Config]
summary: Get video output settings (HDMI/VGA)
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Output config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/OutputConfig"
/API/SystemConfig/User/Get:
post:
operationId: getUsers
tags: [System Config]
summary: Get user accounts
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: User list
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/UserConfig"
/API/SystemConfig/User/Set:
post:
operationId: setUsers
tags: [System Config]
summary: Create/update/delete user accounts
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# NETWORK CONFIG
# ════════════════════════════════════════════════════════════
/API/NetworkConfig/NetBase/Get:
post:
operationId: getNetworkBase
tags: [Network]
summary: Get TCP/IP, port, and network settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Network configuration
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/NetworkBaseConfig"
/API/NetworkConfig/NetBase/Set:
post:
operationId: setNetworkBase
tags: [Network]
summary: Update TCP/IP and port settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/NetworkBaseConfig"
responses:
"200":
description: Updated (may trigger network_changed)
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/NetworkConfig/NetBase/Test:
post:
operationId: testNetwork
tags: [Network]
summary: Test network connectivity
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Test result
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/NetworkConfig/DDNS/Get:
post:
operationId: getDDNS
tags: [Network]
summary: Get DDNS settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: DDNS config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DDNSConfig"
/API/NetworkConfig/Email/Get:
post:
operationId: getEmail
tags: [Network]
summary: Get email notification settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Email config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/EmailConfig"
/API/NetworkConfig/Email/Test:
post:
operationId: testEmail
tags: [Network]
summary: Send test email
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Test result
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/NetworkConfig/Ftp/Get:
post:
operationId: getFTP
tags: [Network]
summary: Get FTP upload settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: FTP config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/FTPConfig"
/API/NetworkConfig/Ftp/Test:
post:
operationId: testFTP
tags: [Network]
summary: Test FTP connection
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Test result
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/NetworkConfig/IPFilter/Get:
post:
operationId: getIPFilter
tags: [Network]
summary: Get IP allow/deny list
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: IP filter config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IPFilterConfig"
/API/NetworkConfig/https/Get:
post:
operationId: getHTTPS
tags: [Network]
summary: Get HTTPS/SSL settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: HTTPS config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/HTTPSConfig"
/API/NetworkConfig/Snmp/Get:
post:
operationId: getSNMP
tags: [Network]
summary: Get SNMP settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: SNMP config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SNMPConfig"
/API/NetworkConfig/Rtmp/Get:
post:
operationId: getRTMP
tags: [Network]
summary: Get RTMP streaming settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: RTMP config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/RTMPConfig"
/API/NetworkConfig/Onvif/Get:
post:
operationId: getOnvif
tags: [Network]
summary: Get ONVIF settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: ONVIF config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/OnvifConfig"
/API/NetworkConfig/SMARTHOME/Get:
post:
operationId: getSmartHome
tags: [Network]
summary: Get smart home integration settings (Amazon Alexa / Google Home)
description: "Verified: returns empty data object when no smart home configured."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Smart home config
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/NetworkConfig/ScanWlan/Scan:
post:
operationId: scanWifi
tags: [Network]
summary: Scan for available WiFi networks
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: WiFi scan results
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/NetworkConfig/ScanWlan/Join:
post:
operationId: joinWifi
tags: [Network]
summary: Connect to a WiFi network
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Join result
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# CHANNEL CONFIG
# ════════════════════════════════════════════════════════════
/API/ChannelConfig/IPChannel/Get:
post:
operationId: getIPChannels
tags: [Channel Config]
summary: Get IP camera channel configuration
description: Returns per-channel camera model, IP, MAC, firmware, protocol, connection status.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: IP channel configuration
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IPChannelConfig"
/API/ChannelConfig/IPChannel/Set:
post:
operationId: setIPChannels
tags: [Channel Config]
summary: Add/update/remove IP camera channels
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/IPChannelConfig"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/ChannelConfig/OSD/Get:
post:
operationId: getOSD
tags: [Channel Config]
summary: Get on-screen display settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: OSD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/OSDConfig"
/API/ChannelConfig/ImageControl/Get:
post:
operationId: getImageControl
tags: [Channel Config]
summary: Get image adjustment settings (brightness, contrast, etc.)
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Image control config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ImageControlConfig"
/API/ChannelConfig/Color/Get:
post:
operationId: getColor
tags: [Channel Config]
summary: Get color/day-night settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Color config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ColorConfig"
/API/ChannelConfig/VideoCover/Get:
post:
operationId: getVideoCover
tags: [Channel Config]
summary: Get privacy mask settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Video cover config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/VideoCoverConfig"
/API/ChannelConfig/ROI/Get:
post:
operationId: getROI
tags: [Channel Config]
summary: Get region of interest encoding settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: ROI config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ROIConfig"
/API/ChannelConfig/PTZ/Get:
post:
operationId: getPTZConfig
tags: [Channel Config]
summary: Get PTZ protocol settings for a channel
description: "Verified: most fixed cameras return {reason: Not support}."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: PTZ config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/PTZConfig"
/API/ChannelConfig/PoePower/Get:
post:
operationId: getPoePower
tags: [Channel Config]
summary: Get PoE power management settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: PoE power config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/PoePowerConfig"
/API/ChannelConfig/DefaultPassword/Get:
post:
operationId: getDefaultPassword
tags: [Channel Config]
summary: Get default password for auto-added cameras
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Default password config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DefaultPasswordConfig"
/API/ChannelConfig/ProtocolManage/Get:
post:
operationId: getProtocolManage
tags: [Channel Config]
summary: Get custom protocol configurations
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Protocol config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ProtocolManageConfig"
/API/ChannelConfig/ModifyIPCPassword/Set:
post:
operationId: modifyIPCPassword
tags: [Channel Config]
summary: Change password on a connected IP camera
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Password changed
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/ChannelConfig/AnalogChannel/Get:
post:
operationId: getAnalogChannel
tags: [Channel Config]
summary: Get analog channel config
description: "Verified: returns empty data (no analog channels on this NVR model)."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Analog channel config
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/ChannelConfig/WirelessCamera/Get:
post:
operationId: getWirelessCamera
tags: [Channel Config]
summary: Get wireless camera config
description: "Verified: returns empty data (no wireless cameras on this NVR model)."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Wireless camera config
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# STREAM CONFIG
# ════════════════════════════════════════════════════════════
/API/StreamConfig/MainStream/Get:
post:
operationId: getMainStream
tags: [Stream Config]
summary: Get mainstream encoding settings
description: Returns per-channel H.264/H.265 settings, resolution, FPS, bitrate, audio, ETR.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Main stream config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/StreamConfig"
/API/StreamConfig/MainStream/Set:
post:
operationId: setMainStream
tags: [Stream Config]
summary: Update mainstream encoding settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/StreamConfig"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/StreamConfig/SubStream/Get:
post:
operationId: getSubStream
tags: [Stream Config]
summary: Get substream encoding settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Sub stream config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/StreamConfig"
/API/StreamConfig/MobileStream/Get:
post:
operationId: getMobileStream
tags: [Stream Config]
summary: Get mobile stream encoding settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Mobile stream config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/StreamConfig"
/API/StreamConfig/Capture/Get:
post:
operationId: getCaptureSettings
tags: [Stream Config]
summary: Get snapshot capture quality settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Capture config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/CaptureConfig"
# ════════════════════════════════════════════════════════════
# RECORD CONFIG
# ════════════════════════════════════════════════════════════
/API/RecordConfig/Get:
post:
operationId: getRecordConfig
tags: [Record]
summary: Get recording settings per channel
description: Returns record switch, stream mode, prerecord, ANR settings.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Record configuration
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/RecordConfig"
/API/RecordConfig/Set:
post:
operationId: setRecordConfig
tags: [Record]
summary: Update recording settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/RecordConfig"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# STORAGE
# ════════════════════════════════════════════════════════════
/API/StorageConfig/Disk/Get:
post:
operationId: getStorageDisk
tags: [Storage]
summary: Get disk information and status
description: Returns HDD model, serial, capacity, free space, overwrite policy.
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Disk information
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/StorageDiskConfig"
/API/StorageConfig/Disk/Format:
post:
operationId: formatDisk
tags: [Storage]
summary: Format a disk
description: Erases all recordings on the specified disk.
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
disk_id:
type: integer
responses:
"200":
description: Format started
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/StorageConfig/Disk/Format/Progress:
post:
operationId: getDiskFormatProgress
tags: [Storage]
summary: Get disk format progress
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Format progress
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/StorageConfig/DiskGroup/Get:
post:
operationId: getDiskGroups
tags: [Storage]
summary: Get disk group configuration
description: "Note: Returns no_support error on AVR-NSV08P8."
x-not-supported: true
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Disk group config (or no_support error)
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/API/StorageConfig/Cloud/Get:
post:
operationId: getCloudStorage
tags: [Storage]
summary: Get cloud storage settings (Dropbox)
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Cloud storage config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/CloudStorageConfig"
# ════════════════════════════════════════════════════════════
# ALARM / EVENT CONFIG
# ════════════════════════════════════════════════════════════
/API/AlarmConfig/Motion/Get:
post:
operationId: getMotionDetection
tags: [Alarm]
summary: Get motion detection settings
description: "Requires page_type:AlarmConfig, channel:0 in request data."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Motion detection config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/MotionDetectionConfig"
/API/AlarmConfig/IO/Get:
post:
operationId: getIOAlarm
tags: [Alarm]
summary: Get I/O alarm settings
description: "Requires page_type:AlarmConfig, channel:0. Keys are alarm input names e.g. Local<-1."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: I/O alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IOAlarmConfig"
/API/AlarmConfig/Deterrence/Get:
post:
operationId: getDeterrence
tags: [Alarm]
summary: Get active deterrence (floodlight/siren) settings
description: "Verified: returns {reason: Not support} per channel on cameras without deterrence."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Deterrence config
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AlarmConfig/Exception/Get:
post:
operationId: getExceptionAlarm
tags: [Alarm]
summary: Get exception alarm settings (disk full, network loss, video loss)
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Exception alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ExceptionAlarmConfig"
/API/AlarmConfig/Intelligent/PID/Get:
post:
operationId: getPID
tags: [Alarm]
summary: Get perimeter intrusion detection alarm settings
description: "Requires page_type:AlarmConfig, channel:0. Unconfigured channels return {reason: Not configured}."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: PID alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/LCD/Get:
post:
operationId: getLCD
tags: [Alarm]
summary: Get line crossing detection alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: LCD alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/SOD/Get:
post:
operationId: getSOD
tags: [Alarm]
summary: Get scene change detection alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: SOD alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/FD/Get:
post:
operationId: getFDAlarm
tags: [Alarm]
summary: Get face detection alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Face detection alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/CC/Get:
post:
operationId: getCCAlarm
tags: [Alarm]
summary: Get cross counting alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Cross counting alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/PD/Get:
post:
operationId: getPDAlarm
tags: [Alarm]
summary: Get person detection alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Person detection alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/SoundDetection/Get:
post:
operationId: getSoundDetection
tags: [Alarm]
summary: Get sound detection alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Sound detection alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Intelligent/OcclusionDetection/Get:
post:
operationId: getOcclusionDetection
tags: [Alarm]
summary: Get occlusion detection alarm settings
description: "Verified: returns {reason: Not support} per channel."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Occlusion detection alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAlarmConfig"
/API/AlarmConfig/Combination/Get:
post:
operationId: getCombinationAlarm
tags: [Alarm]
summary: Get combination alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Combination alarm config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/CombinationAlarmConfig"
/API/AlarmConfig/PTZLinkage/Get:
post:
operationId: getPTZLinkage
tags: [Alarm]
summary: Get PTZ linkage alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: PTZ linkage config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/PTZLinkageConfig"
/API/AlarmConfig/VoicePrompts/Get:
post:
operationId: getVoicePrompts
tags: [Alarm]
summary: Get voice prompt alarm settings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
control_type:
type: string
enum: [Normal, AiFace, AiPlate]
download_mode:
type: string
enum: [mp3]
page:
type: string
responses:
"200":
description: Voice prompts config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/VoicePromptsConfig"
/API/AlarmConfig/VoiceAlarm/Get:
post:
operationId: getVoiceAlarm
tags: [Alarm]
summary: Get voice alarm settings
description: "Verified: returns {reason: Not support} per channel."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Voice alarm config
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AlarmConfig/Disarming/Get:
post:
operationId: getDisarming
tags: [Alarm]
summary: Get alarm disarming schedule
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Disarming config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DisarmingConfig"
/API/AlarmConfig/Schedule/Get:
post:
operationId: getAlarmSchedule
tags: [Alarm]
summary: Get alarm schedule
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
page_type:
type: string
enum: [AlarmConfig]
channel:
type: array
items:
type: integer
responses:
"200":
description: Alarm schedule
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# PREVIEW / LIVE VIEW
# ════════════════════════════════════════════════════════════
/live.mp4:
get:
operationId: getLiveStream
tags: [Preview]
summary: Get live fMP4 video stream
description: |
Returns a fragmented MP4 stream for playback via Media Source Extensions (MSE).
Requires session cookie and CSRF token header.
parameters:
- name: channel
in: query
required: true
schema:
type: integer
description: 0-based channel index
- name: type
in: query
required: true
schema:
$ref: "#/components/schemas/StreamTypeEnum"
- name: chrome
in: query
schema:
type: integer
enum: [1]
responses:
"200":
description: Fragmented MP4 video stream
content:
video/mp4:
schema:
type: string
format: binary
/API/PreviewChannel/PTZ/Get:
post:
operationId: getPTZStatus
tags: [Preview]
summary: Get PTZ status for a channel
description: "Requires channel:CH1 (string) in request data."
requestBody:
$ref: "#/components/requestBodies/PTZChannelRequest"
responses:
"200":
description: PTZ status
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/PreviewPTZGetResponse"
/API/PreviewChannel/PTZ/Range:
post:
operationId: getPTZRange
tags: [Preview]
summary: Get PTZ capabilities for a channel
description: "Requires channel:CH1 (string) in request data."
requestBody:
$ref: "#/components/requestBodies/PTZChannelRequest"
responses:
"200":
description: PTZ capabilities
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/PreviewChannel/PTZ/Control:
post:
operationId: controlPTZ
tags: [Preview]
summary: Send PTZ command
description: Control pan/tilt/zoom, presets, cruise, focus, iris, etc.
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/PTZControlRequest"
responses:
"200":
description: Command accepted
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/PreviewChannel/ManualAlarm:
post:
operationId: triggerManualAlarm
tags: [Preview]
summary: Trigger or stop manual alarm on a channel
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Alarm triggered
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/PreviewChannel/Floodlight2AudioAlarm:
post:
operationId: triggerDeterrenceAlarm
tags: [Preview]
summary: Trigger floodlight or audio alarm deterrence
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Deterrence triggered
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# PLAYBACK
# ════════════════════════════════════════════════════════════
/API/Playback/SearchMonth/Get:
post:
operationId: searchMonth
tags: [Playback]
summary: Search for days with recordings in a month
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/SearchMonthRequest"
responses:
"200":
description: Days with recordings
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Playback/SearchRecord/Search:
post:
operationId: searchRecords
tags: [Playback]
summary: Search for recording segments in a time range
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/SearchDayRequest"
responses:
"200":
description: Recording segments
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Playback/PlaybackPage/Range:
post:
operationId: getPlaybackPageRange
tags: [Playback]
summary: Get playback page capabilities and record type filters
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Playback page range
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/GetDashPlaybackUrl:
get:
operationId: getDashPlaybackUrl
tags: [Playback]
summary: Get DASH playback URLs
description: Returns MPD manifest URL, keepalive URL, and stop URL for DASH playback.
responses:
"200":
description: Playback URLs
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
mpd:
type: string
description: DASH MPD manifest URL
keepalive:
type: string
description: Keepalive ping URL (send every 10s)
stop:
type: string
description: Stop playback URL
/API/Snapshot/Range:
post:
operationId: getSnapshotRange
tags: [Playback]
summary: Get available snapshot resolutions per channel
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
reset_session_timeout:
type: boolean
default: false
responses:
"200":
description: Snapshot capabilities
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SnapshotRangeResponse"
/API/Snapshot/Get:
post:
operationId: getSnapshot
tags: [Playback]
summary: Capture a live snapshot from a channel
description: Returns a base64-encoded JPEG image.
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/SnapshotRequest"
responses:
"200":
description: Snapshot image
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/SnapshotResponse"
/API/Playback/Tag/Get:
post:
operationId: getPlaybackTags
tags: [Playback]
summary: Get recording bookmarks/tags
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Playback tags
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/download.mp4:
post:
operationId: downloadRecording
tags: [Playback]
summary: Download a recording clip as MP4
parameters:
- name: start_time
in: query
required: true
schema:
type: string
description: Format YYYYMMDDHHmmss
- name: end_time
in: query
required: true
schema:
type: string
- name: channel
in: query
required: true
schema:
type: integer
- name: record_type
in: query
schema:
$ref: "#/components/schemas/RecordTypeBitmask"
- name: stream_type
in: query
schema:
$ref: "#/components/schemas/StreamTypeEnum"
- name: record_id
in: query
schema:
type: string
- name: disk_event_id
in: query
schema:
type: string
responses:
"200":
description: MP4 file download
content:
video/mp4:
schema:
type: string
format: binary
# ════════════════════════════════════════════════════════════
# EVENTS (Long Polling)
# ════════════════════════════════════════════════════════════
/API/Event/Check:
post:
operationId: checkEvents
tags: [Events]
summary: Long-poll for real-time alarm/event notifications
description: |
First call with empty data to get initial cursor (reader_id, sequence, lap_number).
Subsequent calls pass cursor values to receive new events since last check.
Returns immediately if events are pending, otherwise blocks until timeout.
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
$ref: "#/components/schemas/EventCheckRequest"
responses:
"200":
description: Event data or empty poll
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/EventCheckResponse"
# ════════════════════════════════════════════════════════════
# AI ANALYTICS
# ════════════════════════════════════════════════════════════
/API/AI/Setup/FD/Get:
post:
operationId: getAIFaceDetection
tags: [AI]
summary: Get AI face detection setup
description: "Verified: returns empty object per channel when not configured."
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI face detection config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIFaceDetectionConfig"
/API/AI/Setup/PVD/Get:
post:
operationId: getAIPersonVehicle
tags: [AI]
summary: Get AI person/vehicle detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI PVD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/PID/Get:
post:
operationId: getAIPerimeterIntrusion
tags: [AI]
summary: Get AI perimeter intrusion detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI PID config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/LCD/Get:
post:
operationId: getAILineCrossing
tags: [AI]
summary: Get AI line crossing detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI LCD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/LPD/Get:
post:
operationId: getAILicensePlate
tags: [AI]
summary: Get AI license plate detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI LPD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/CrossCount/Get:
post:
operationId: getAICrossCount
tags: [AI]
summary: Get AI cross counting setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI cross counting config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/HeatMap/Get:
post:
operationId: getAIHeatMap
tags: [AI]
summary: Get AI heat map setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI heat map config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIHeatMapConfig"
/API/AI/Setup/CD/Get:
post:
operationId: getAICrowdDensity
tags: [AI]
summary: Get AI crowd density detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI CD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/QD/Get:
post:
operationId: getAIQueueDetection
tags: [AI]
summary: Get AI queue detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI QD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/RSD/Get:
post:
operationId: getAIRunningSpeedDetection
tags: [AI]
summary: Get AI running speed detection setup
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI RSD config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAlarmSetupConfig"
/API/AI/Setup/AISchedule/Get:
post:
operationId: getAIScheduleSetup
tags: [AI]
summary: Get AI analytics schedule per channel
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: AI schedule config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIScheduleConfig"
/API/AI/Model/Get:
post:
operationId: getAIModel
tags: [AI]
summary: Get AI model versions per channel
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: AI model config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIModelConfig"
/API/AI/Alarm/AttributeDetect/Get:
post:
operationId: getAIAttributeDetect
tags: [AI]
summary: Get AI attribute detection alarm settings
requestBody:
$ref: "#/components/requestBodies/AlarmConfigRequest"
responses:
"200":
description: Attribute detection config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIAttributeDetectConfig"
/API/AI/CCStatistics/Get:
post:
operationId: getAICCStatistics
tags: [AI]
summary: Get AI cross counting statistics
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: CC statistics
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AICCStatisticsConfig"
/API/AI/FDAttendance/Get:
post:
operationId: getAIFDAttendance
tags: [AI]
summary: Get face detection attendance settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: FD attendance config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIFDAttendanceConfig"
/API/AI/HeatMapStatistics/Get:
post:
operationId: getAIHeatMapStatistics
tags: [AI]
summary: Get AI heat map statistics
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Heat map statistics
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AIHeatMapStatisticsConfig"
/API/AI/FDGroup/Get:
post:
operationId: getFaceGroups
tags: [AI]
summary: Get face recognition groups
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
TypeFlags:
type: integer
default: 1
DefaultVal:
type: integer
default: 0
WithInternal:
type: integer
default: 0
SimpleInfo:
type: integer
enum: [0, 1]
GroupsId:
type: array
items:
type: integer
responses:
"200":
description: Face groups
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/FDGroup/Add:
post:
operationId: addFaceGroup
tags: [AI]
summary: Create a face recognition group
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
Group:
type: array
items:
type: object
properties:
Id:
type: integer
default: -1
Name:
type: string
DetectType:
type: integer
Policy:
type: integer
Enabled:
type: integer
enum: [0, 1]
responses:
"200":
description: Group created
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/Faces/Add:
post:
operationId: addFace
tags: [AI]
summary: Add a face to a recognition group
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
Count:
type: integer
FaceInfo:
type: array
items:
type: object
responses:
"200":
description: Face added
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/SnapedFaces/Search:
post:
operationId: searchSnappedFaces
tags: [AI]
summary: Search for detected faces in recordings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
StartTime:
type: string
EndTime:
type: string
Chn:
type: array
items:
type: integer
AlarmGroup:
type: array
items:
type: integer
Similarity:
type: integer
Engine:
type: integer
default: 1
Count:
type: integer
FaceInfo:
type: array
items:
type: object
responses:
"200":
description: Search initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/SnapedObjects/Search:
post:
operationId: searchSnappedObjects
tags: [AI]
summary: Search for detected objects (person/vehicle) in recordings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
StartTime:
type: string
EndTime:
type: string
Chn:
type: array
items:
type: integer
Type:
type: string
description: Detection type filter
Engine:
type: integer
default: 1
responses:
"200":
description: Search initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/SnapedObjects/SearchPlate:
post:
operationId: searchLicensePlates
tags: [AI]
summary: Search for detected license plates in recordings
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
StartTime:
type: string
EndTime:
type: string
Chn:
type: array
items:
type: integer
AlarmGroup:
type: array
items:
type: integer
PlatesId:
type: array
items:
type: string
MaxErrorCharCnt:
type: integer
SortType:
type: integer
default: 0
Engine:
type: integer
default: 1
responses:
"200":
description: Search initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/PlateGroup/Get:
post:
operationId: getPlateGroups
tags: [AI]
summary: Get license plate recognition groups
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
DefaultVal:
type: integer
default: 0
SimpleInfo:
type: integer
GroupsId:
type: array
items:
type: integer
responses:
"200":
description: Plate groups
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/ObjectStatistics/Get:
post:
operationId: getObjectStatistics
tags: [AI]
summary: Get object counting statistics
requestBody:
content:
application/json:
schema:
type: object
properties:
version:
type: string
data:
type: object
properties:
MsgId:
type: string
TimePoints:
type: array
items:
type: string
Chn:
type: array
items:
type: integer
Type:
type: string
Engine:
type: integer
default: 1
responses:
"200":
description: Statistics data
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/AI/processAlarm/Get:
post:
operationId: getAIAlarmReport
tags: [AI]
summary: Get AI alarm processing report
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: AI alarm report
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Intelligent/IntelligentAnalysis/Get:
post:
operationId: getIntelligentAnalysis
tags: [AI]
summary: Get intelligent analysis config
description: "Verified: returns {reason: Not configured} per channel."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Intelligent analysis config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/IntelligentAnalysisConfig"
# ════════════════════════════════════════════════════════════
# SCHEDULES
# ════════════════════════════════════════════════════════════
/API/Schedules/Record/Get:
post:
operationId: getRecordSchedule
tags: [Schedules]
summary: Get recording schedule
description: "Verified: returns category array with schedule_type Normal, Motion, IO, etc."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Record schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/Record/Set:
post:
operationId: setRecordSchedule
tags: [Schedules]
summary: Update recording schedule
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Updated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Schedules/Capture/Get:
post:
operationId: getCaptureSchedule
tags: [Schedules]
summary: Get snapshot capture schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Capture schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/Alarm/Get:
post:
operationId: getAlarmActionSchedule
tags: [Schedules]
summary: Get alarm action schedule
description: "Verified: returns schedule_type AlarmOut."
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Alarm schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/Email/Get:
post:
operationId: getEmailSchedule
tags: [Schedules]
summary: Get email notification schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Email schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/Ftp/Get:
post:
operationId: getFTPSchedule
tags: [Schedules]
summary: Get FTP upload schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: FTP schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/AI/Get:
post:
operationId: getAISchedule
tags: [Schedules]
summary: Get AI analytics schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: AI schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/Intelligent/Get:
post:
operationId: getIntelligentSchedule
tags: [Schedules]
summary: Get intelligent analytics schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Intelligent schedule
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ScheduleConfig"
/API/Schedules/Deterrence/Get:
post:
operationId: getDeterrenceSchedule
tags: [Schedules]
summary: Get deterrence (floodlight) schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Deterrence schedule
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# MAINTENANCE
# ════════════════════════════════════════════════════════════
/API/Maintenance/Log/Search:
post:
operationId: searchLogs
tags: [Maintenance]
summary: Search system logs
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: Log entries
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/DeviceReboot/Set:
post:
operationId: rebootDevice
tags: [Maintenance]
summary: Reboot the NVR
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Reboot initiated (includes restart_time)
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/DeviceShutdown/Set:
post:
operationId: shutdownDevice
tags: [Maintenance]
summary: Shut down the NVR
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Shutdown initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/Factory/Set:
post:
operationId: factoryReset
tags: [Maintenance]
summary: Factory reset the NVR
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Factory reset initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/Reset/Set:
post:
operationId: loadDefaults
tags: [Maintenance]
summary: Reset settings to defaults (preserving network)
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Settings reset
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/ResetSettings/Get:
post:
operationId: getResetSettings
tags: [Maintenance]
summary: Get reset settings options
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Reset settings config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/ResetSettingsConfig"
/API/Maintenance/AutoReboot/Get:
post:
operationId: getAutoReboot
tags: [Maintenance]
summary: Get auto-reboot schedule
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Auto-reboot config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AutoRebootConfig"
/API/Maintenance/DeveloperMode/Get:
post:
operationId: getDeveloperMode
tags: [Maintenance]
summary: Get developer mode status
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Developer mode status
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DeveloperModeConfig"
/API/Maintenance/FtpUpgrade/Get:
post:
operationId: getFtpUpgrade
tags: [Maintenance]
summary: Get FTP upgrade settings
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: FTP upgrade config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/FtpUpgradeConfig"
/API/Maintenance/FtpUpgrade/Check:
post:
operationId: checkFTPUpgrade
tags: [Maintenance]
summary: Check for firmware upgrade on FTP server
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: FTP upgrade check result
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/SystemUpgrade/Token/Get:
post:
operationId: getUpgradeToken
tags: [Maintenance]
summary: Get upload token for firmware upgrade
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Upgrade token
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/SystemUpgrade/Upgrade:
post:
operationId: uploadFirmware
tags: [Maintenance]
summary: Upload and apply firmware upgrade
description: Requires X-Upgrade-Token header from getUpgradeToken.
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
"200":
description: Upgrade started
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Maintenance/ParamManagement/Export:
post:
operationId: exportParams
tags: [Maintenance]
summary: Export device configuration backup
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Configuration backup file
content:
application/octet-stream:
schema:
type: string
format: binary
/API/Maintenance/ParamManagement/Import:
post:
operationId: importParams
tags: [Maintenance]
summary: Import device configuration backup
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
"200":
description: Configuration imported
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/IPCMaintaint/IPCUpgrade/Token:
post:
operationId: getIPCUpgradeToken
tags: [Maintenance]
summary: Get upload token for IP camera firmware upgrade
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: IPC upgrade token
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/IPCMaintaint/IPCReboot/Set:
post:
operationId: rebootIPC
tags: [Maintenance]
summary: Reboot a connected IP camera
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: IPC reboot initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/IPCMaintaint/IPCReset/Set:
post:
operationId: resetIPC
tags: [Maintenance]
summary: Factory reset a connected IP camera
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: IPC reset initiated
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/IPCMaintaint/IPCDisk/Format:
post:
operationId: formatIPCDisk
tags: [Maintenance]
summary: Format SD card on a connected IP camera
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ApiRequest"
responses:
"200":
description: IPC disk format started
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
# ════════════════════════════════════════════════════════════
# MISC
# ════════════════════════════════════════════════════════════
/API/DeviceConfig/Audio/Get:
post:
operationId: getAudioConfig
tags: [Channel Config]
summary: Get device audio settings (two-way talk, volume)
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Audio config
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/AudioConfig"
/API/RemoteReport/Get:
post:
operationId: getRemoteReport
tags: [System Info]
summary: Get remote reporting status
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Remote report data
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/UI/Setup/Get:
post:
operationId: getSetupMenu
tags: [System Config]
summary: Get setup menu structure
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Menu structure
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessResponse"
/API/Login/DevicePage/Get:
post:
operationId: getDevicePages
tags: [System Config]
summary: Get available configuration pages for the device
requestBody:
$ref: "#/components/requestBodies/EmptyApiRequest"
responses:
"200":
description: Available pages
content:
application/json:
schema:
type: object
properties:
result:
type: string
data:
$ref: "#/components/schemas/DevicePageResponse"
@splch
Copy link
Author

splch commented Mar 15, 2026

Security Audit & Exploitation Findings — Avycon AVR-NSV08P8

Device Profile

  • Model: AVR-NSV08P8 (Diversity Series 8-Ch 4K NVR, 8 PoE)
  • SoC: Novatek (SNMP enterprise OID 51159), board DM-443
  • OS: Linux NVTEVM 4.9.118 armv7l (kernel compiled Jan 3, 2023)
  • Firmware: V8.2.3.2-20230816 | Web Client V1.3.1.7 | HTTP API V1.026
  • Services: HTTP (80), HTTPS (443), RTSP (554), Media (9000), SNMP (161/udp), Telnet (23 when enabled)
  • ONVIF: Hikvision-derived (hikxsd namespace), gSOAP-based

Critical Vulnerabilities Found

1. Unauthenticated Live Video via HLS

Any device on the network can view all camera feeds with zero authentication:

curl http://<NVR_IP>/hls/live/CH1/0/livetop.mp4 -o video.mp4

All channels and substreams confirmed exposed. 57MB of live video downloaded without cookies, tokens, or credentials.

2. RTSP Buffer Overflow (DoS confirmed, RCE likely)

The NVR's RTSP server on port 554 crashes when sent a DESCRIBE request with a ~256-byte URI:

DESCRIBE rtsp://<IP>:554/<256+ 'A' chars> RTSP/1.0\r\nCSeq: 1\r\n\r\n
  • Service crashes and does NOT auto-restart
  • Classic stack buffer overflow on embedded ARM (armv7l)
  • Likely exploitable for RCE given typical lack of ASLR/NX on this class of device
  • Similar to CVE-2022-26259 (Xiongmai RTSP overflow)
  • Note: The cameras' RTSP servers survived the same payload — only the NVR's RTSP is vulnerable

3. SNMPv1 with Default Community Strings

  • Read: public — full device enumeration (OS, kernel, channels, streams, disk, network)
  • Write: private — writable OIDs include sysName, sysContact, sysLocation, IP address, client port
  • Entire enterprise MIB (OID 1.3.6.1.4.1.51159) readable
  • NET-SNMP EXTEND MIB is compiled in but write-protected (noAccess not noSuchName)

4. Telnet Enableable Without Secondary Auth

POST /API/Maintenance/DeveloperMode/Set
{"version":"1.0","data":{"telnet_switch":true}}

Any authenticated web user can open telnet. Root password is hardcoded in firmware — survives factory reset.

5. P2P Cloud + Globally Routable IPv6

Device reachable from internet via vendor P2P relay and globally routable IPv6. Combined with HLS auth bypass, live feeds may be internet-accessible.


High Findings

  • No HTTP→HTTPS redirect — full web UI served over cleartext
  • Session cookie missing Secure and SameSite flags
  • No IP access filtering configured
  • Firmware 2.5+ years old, kernel 4.9.118 has hundreds of known CVEs
  • JavaScript uses eval() with unsafe-eval CSP
  • gSOAP likely vulnerable to CVE-2017-9765 (Devil's Ivy) but 10s connection timeout prevents 2GB payload delivery

Exploitation Attempts (26 vectors tested)

Telnet (port 23)

Technique Result
Brute force (100+ passwords incl. Novatek/HiSilicon/Xiongmai defaults) All rejected
CVE-2026-24061 USER env injection (-f root) BusyBox telnetd, no NEW-ENVIRON support
Buffer overflow (up to 8KB username/password) Login survived
Format string (%x, %n, %s, %p) No effect
Null byte / special char passwords All rejected

SNMP (port 161)

Technique Result
EXTEND MIB RCE (SNMPv1 raw OIDs) noSuchName — v1 can't resolve
EXTEND MIB RCE (SNMPv2c raw OIDs) noAccess — MIB present but write-protected
SNMPv3 EXTEND after reconfiguring auth Auth failure
Enterprise OID write Works but no exec capability

ONVIF / gSOAP

Technique Result
XXE injection (file:///etc/passwd) Entities stripped
SetHostname cmd injection ($(id)) Accepted (200 OK) but not executed
SetNTP cmd injection (telnetd payload) Accepted but NTP uses library calls, not shell
Devil's Ivy CVE-2017-9765 Blocked — 10s timeout, only ~1.1MB through (needs 2.15GB)

RTSP

Technique Result
DESCRIBE URI overflow on port 554 CRASHED! Confirmed buffer overflow
Same overflow via port 80 RTSP handler Survived — different/stub code on port 80
Header overflows on port 80 All survived

Web API

Technique Result
Command injection in NTP/DDNS/FTP/Email Input validation blocks all
Path traversal (HLS + API endpoints) Properly blocked
HTTP URL overflow (up to 65KB) Server survived
HTTP header overflow (up to 32KB) Server survived
Config export via PBKDF2 secondary auth Exported! But encrypted with internal key, not auth key
User creation via API Needs X25519 encrypted password fields
Firmware upload token Auth accepted but unknown data format
FTP/HTTP firmware delivery NVR downloads our file but can't parse format

USB Physical Access

Technique Result
28 trigger files (telnet_enable, dvr_app, autorun.sh, NVT_DEBUG, etc.) Not recognized by Novatek firmware

System Reset

Technique Result
Factory reset "system" component via API Successful, but telnet root password unchanged (hardcoded)

Key Technical Achievements

  1. PBKDF2 secondary authentication reverse-engineered — Extracted the NVR's JavaScript crypto module (module 512), replicated the exact forge.pkcs5.pbkdf2 → hex → base64 chain in Node.js, and successfully authenticated to export encrypted device config

  2. RTSP buffer overflow discovered — New vulnerability in the NVR's RTSP DESCRIBE handler. ~256-byte URI crashes the service permanently. ARM armv7l target with likely no ASLR/PIE. Similar to CVE-2022-26259.

  3. SNMP EXTEND MIB confirmed compiled innoAccess response (not noSuchName) proves the NET-SNMP-EXTEND-MIB module exists but is ACL-restricted. The Metasploit exploit/linux/snmp/net_snmpd_rw_access module would work if the view was opened.

  4. Complete API reverse-engineering — 229 endpoints tested, 156 with full response schemas. OpenAPI 3.1.0 spec: 6,177 lines, 158 operations, 106 typed component schemas.

  5. X25519 + AES-GCM password encryption implemented — Full encryptPassword flow working in Node.js for authenticated API operations.


Negative Findings (Good Security)

  • Path traversal properly blocked (http_format_err)
  • CORS not enabled (blocks cross-origin attacks)
  • Snapshot/Download endpoints require authentication
  • Default web credentials rejected
  • CSP, X-Frame-Options, X-Content-Type-Options headers present
  • No CGI endpoints (AVTECH CVE-2024-7029 not applicable)
  • Web server survived 65KB URL and 32KB headers without crashing

Remaining Attack Paths

Path A: RTSP Buffer Overflow Exploitation

Re-enable port 554 (full factory reset), then exploit the overflow with ARM ROP chain to call system("telnetd -l /bin/sh -p 2323"). Research indicates these NVR ARM binaries typically lack PIE, making ROP feasible with static addresses.

Path B: UART Serial Console

Physical access to DM-443 board debug header. Novatek boards provide root shell on UART at 115200 baud with no password.

Path C: Firmware Binary Analysis

Extract .sw firmware file → binwalk → find /etc/shadow → crack root password hash.

@splch
Copy link
Author

splch commented Mar 15, 2026

Final Update: UART Required for Root Access

After exhaustive testing (160+ passwords, 30+ exploit vectors, USB attacks, firmware crafting, local GUI injection, SNMP escalation, ONVIF exploitation, debug log analysis), the root password is confirmed hardcoded in the NAND flash ramdisk partition and cannot be obtained or bypassed through any remote or USB-based method.

Firmware verification is CRC16 only (no crypto signatures) — confirmed via Novatek U-Boot source analysis. Custom firmware can be crafted with valid CRCs, but the NVR's application-level firmware parser rejects files that don't match its expected NVTPACK structure (which requires the original firmware as a template).

UART serial console (ttyS0 @ 115200 baud) is the definitive path to root. A $5 CP2102 USB-to-TTL adapter connected to the DM-443 board's debug header provides direct root shell access.

Key technical findings from the full investigation:

  • SoC: Novatek NA51068 (confirmed via dmesg and SNMP)
  • No secure boot in U-Boot config (CONFIG_SECURE_BOOT absent)
  • NET-SNMP EXTEND MIB compiled in but VACM write-protected
  • RTSP buffer overflow at ~256 bytes (port 554, confirmed crash)
  • Unauthenticated HLS video streams
  • ONVIF gSOAP likely unpatched (CVE-2017-9765) but timeout prevents exploitation
  • USB autostart scripts not supported by this firmware
  • Web and telnet authentication systems are completely independent
  • Debug export writes application logs to USB (not system/auth logs)

Complete device profile and all exploit scripts at: github gist above + /nvr_pentest/ directory

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment