Developer ResourcesAiFace WebServer API Documentation
Download PDF

AiFace Device Web API Protocol Documentation (English)

Version: 1.0

Based on: webserver.cpp source code analysis

Protocol: HTTP + JSON

⚠️ Protocol Role Note: In the WebServer API, the device acts as an HTTP server, and browsers or other clients access the device as requesters. Therefore, this protocol is restricted to Local Area Network (LAN) use only — clients must be on the same network segment as the device to access it.

1. Overview

This document describes the HTTP API protocol of the embedded web server in AiFace facial recognition access control devices.

1.1 Server Architecture

ModePortDescription
HTTP80 (default) or customStandard HTTP

2. Connection & Authentication

2.1 Login Flow

Except for the getlang command, all /api commands require a password field in the request. The password is configured in the device's settings menu (mapped to DI_WEBSERVER_PWD).

Note: If no password has been set on the device (empty password), all password-required endpoints will return an error.

2.2 Request Endpoint

All JSON API requests are sent to:

POST http://<device_IP>:<port>/api
Content-Type: application/json

3. Common Request Format

JSON{
  "cmd": "<command_name>",
  "password": "<device_password>",
  // ... command-specific parameters
}
FieldTypeRequiredDescription
cmdstringYesCommand name
passwordstringYes (except getlang)Device management password

4. Common Response Format

JSON{
  "ret": "<command_name>",
  "sn": "<device_serial_number>",
  "result": true/false,
  // ... command-specific response data
}
FieldTypeDescription
retstringEchoes the request command name
snstringDevice serial number
resultboolWhether the operation succeeded
reasonnumberFailure reason code (only on failure)
msgstringFailure description text (only on failure)

5. Error Codes

reasonDescription
1User not found / Parameter format error
2Password incorrect / Password is empty
3Device busy (e.g., enrollment in progress)
5No face detected in image
6Multiple faces detected in image
7Image resolution too large
8Face area too large
9Face area too small
10Image quality too low
11Face position too off-center
12Duplicate face (already registered to another user)

6. HTTP Route Endpoints

EndpointMethodDescription
/apiPOSTMain JSON API entry point
/api/firmware/uploadPOSTChunked firmware upload
/download/reportGETDownload summary report (.xls)
/download/rawrecordGETDownload raw attendance records (.xls)
/photos/GETAccess user enrollment photos
/logphotos/GETAccess attendance log snapshot photos
/GETStatic file server (from /usr/webserver or /data/res/webserver)

7. JSON API Command Reference

7.1 Authentication & Device Info


7.1.1 `getlang` — Get Current Language

No password required

Request:

JSON{ "cmd": "getlang" }

Response:

JSON{
  "ret": "getlang",
  "sn": "SN123456",
  "result": true,
  "lang": "English"
}
FieldTypeDescription
langstringCurrent language name

7.1.2 `getlangoption` — Get Available Language List

Request:

JSON{ "cmd": "getlangoption", "password": "xxx" }

Response:

JSON{
  "ret": "getlangoption",
  "sn": "SN123456",
  "result": true,
  "lang": "English",
  "langs": [
    { "lvalue": 0, "ltitle": "English" },
    { "lvalue": 1, "ltitle": "简体中文" }
  ]
}
FieldTypeDescription
langstringCurrently active language
langsarrayAvailable language list (only languages enabled in device settings)
langs[].lvaluenumberLanguage code
langs[].ltitlestringLanguage display name

7.1.3 `login` — Login Verification

Request:

JSON{
  "cmd": "login",
  "username": "admin",
  "password": "xxx"
}
FieldTypeRequiredDescription
usernamestringYesMust be "admin"
passwordstringYesDevice password

Response (success):

JSON{
  "ret": "login",
  "sn": "SN123456",
  "result": true
}

Response (failure):

JSON{
  "ret": "login",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "username error"
}

7.1.4 `reg` — Get Full Device Registration Info

Request:

JSON{ "cmd": "reg", "password": "xxx" }

Response devinfo field breakdown:

FieldTypeDescription
modelnamestringDevice model name
manufacturerstringManufacturer
fpalgostringFingerprint algorithm version (e.g., "thbio3.0")
firmwarestringFirmware version
timestringCurrent device time YYYY-MM-DD HH:MM:SS
curipstringCurrent IP address
macstringMAC address
timezonestringTimezone string
bandwidth_upstringUpload bandwidth
bandwidth_downstringDownload bandwidth
disksizestringTotal disk capacity (MB)
useddiskstringUsed disk space (MB)
deviceidnumberDevice ID
usersizenumberMax user capacity
facesizenumberMax face enrollment capacity
avatarsizenumberMax avatar capacity
fpsizenumberMax fingerprint capacity
palmsizenumberMax palm print capacity
cardsizenumberMax card capacity
pwdsizenumberMax password capacity
logsizenumberMax log capacity
usedusernumberCurrent enrolled user count
usedfacenumberCurrent enrolled face count
usedavatarnumberCurrent enrolled avatar count
usedfpnumberCurrent enrolled fingerprint count
usedpalmnumberCurrent enrolled palm print count
usedcardnumberCurrent enrolled card count
usedpwdnumberCurrent enrolled password count
usedlognumberTotal log count
usednewlognumberNew (unread) log count
usedrtlognumberReal-time log count
netinusenumberActive network: 0=none, 1=wired, 2=WiFi, 3=4G
usb4gnumberUSB 4G dongle present: 0/1
batterynumberBattery level
cpu_tempnumberCPU temperature (°C)
intercomnumberIntercom supported: 0/1
elevator_controlnumberElevator control enabled: 0/1
floorsnumberTotal floor count
base_floornumberBase floor number
have_g_floornumberHas G (ground) floor: 0/1
acces_stimesnumberAccess times
charidnumberCharacter ID
useosdpnumberOSDP protocol in use: 0/1
facetemplatenumberFace template mode
usequestionnumberQuestionnaire enabled: 0/1
onlinedebugnumberOnline debug mode: 0/1
dislanguagenumberDisabled language bitmask
ntpnumberNTP enabled: 0/1
station_mccnumberStation MCC
station_mncnumberStation MNC
station_lacnumberStation LAC
station_cidnumberStation CID
gprsipstring4G module IP
gprsmacstring4G module MAC
gprsversionstring4G module model
gprsimeistring4G module IMEI

7.1.5 `getdevinfo` — Get Device Configuration Parameters

Request:

JSON{ "cmd": "getdevinfo", "password": "xxx" }

Response: Returns all DI_* configuration key-value pairs.

Response Example:

JSON{
  "ret": "getdevinfo",
  "sn": "SN123456",
  "result": true,
  "deviceid": 1,
  "language": 0,
  "managers": 1,
  "verifymode": 0,
  "volume": 80,
  "netipaddress": "192.168.1.100",
  "serverip": "192.168.1.200",
  "wlan_ssid": "MyWiFi",
  "door_opentime": 5,
  "live_detect": 1,
  "fcmatch_level": 60
}

Complete Configuration Parameter List:

##### General Settings

FieldTypeDescription
deviceidnumberDevice ID
languagenumberLanguage
managersnumberNumber of administrators
verifymodenumberVerification mode (see Appendix 10)
volumenumberVolume
video_claritynumberVideo clarity
micvolumenumberMicrophone volume
intercomvolumenumberIntercom volume
date_formatnumberDate format
label_stylenumberLabel style
keyboardnumberKeyboard settings
usegpsnumberUse GPS
time_formatnumberTime format
use_dstnumberUse daylight saving time
dst_startnumberDST start time
dst_endnumberDST end time
show_avatarnumberShow avatar
show_batterynumberShow battery
use_qrcodenumberEnable QR code
screensavertimenumberScreen saver timeout (seconds)
showresulttimenumberVerification result display time (seconds)
sleeptimenumberSleep time (seconds)
screensaver_wakeupnumberScreen saver wake-up mode
stranger_photonumberStranger photo
stranger_locknumberStranger lock
verifyfail_hintnumberVerification failure hint
userid_formatnumberUser ID format
rfid_free_regnumberRFID free registration
rfid_auto_regnumberRFID auto registration
shift_weekend_otnumberShift weekend overtime
rfid_module_typenumberRFID module type
filllightnumberFill light
filllight_periodnumberFill light period
accept_dosenumberAccept dose
face_double_checknumberFace double check
glog_warningnumberGate log warning threshold
slog_warningnumberSystem log warning threshold
reverifytimenumberRe-verification interval (seconds)
use_logphotonumberUse log photo
tts_voicenumberTTS voice
online_debugnumberOnline debug
hide_otanumberHide OTA upgrade
multifacesnumberMulti-face recognition
disable_menunumberDisable menu
server_keypadnumberServer keypad
keypad_pwdnumberKeypad password
reverify_nolocknumberRe-verify without lock
default_shiftnumberDefault shift
saturday_attendnumberSaturday attendance
sunday_attendnumberSunday attendance
allow_latetimenumberAllowed late time (minutes)
allow_earlytimenumberAllowed early leave time (minutes)
auto_signnumberAuto sign-in
shift_weekendnumberShift weekend
excel_passwordstringExcel export password
nosavelognumberDo not save logs
hide_privacynumberPrivacy protection
reboottime1numberScheduled reboot time 1
reboottime2numberScheduled reboot time 2
reboottime3numberScheduled reboot time 3
reg_card_1numberRegistration card 1
reg_card_2numberRegistration card 2
reg_card_3numberRegistration card 3
selfchecklognumberSelf-check log
questionnairenumberQuestionnaire
questionnaire_cardnumberQuestionnaire card
questionnaire_switch_cardnumberQuestionnaire switch card
event_schedulenumberEvent schedule 0
event_schedule1numberEvent schedule 1
event_schedule2numberEvent schedule 2
event_schedule3numberEvent schedule 3
event_schedule4numberEvent schedule 4
event_schedule5numberEvent schedule 5
event_schedule6numberEvent schedule 6
event_schedule7numberEvent schedule 7
event_schedule8numberEvent schedule 8
bellcountnumberBell count
belloutputnumberBell output
ring_stylenumberRing style

##### Biometric Settings

FieldTypeDescription
live_detectnumberLiveness detection switch
live_levelnumberLiveness detection level
fcmatch_levelnumberFace matching threshold
identify_distancenumberIdentification distance
fpmatch_levelnumberFingerprint matching threshold
palm_vein_levelnumberPalm vein level
palm_det_levelnumberPalm detection level
fps_perusernumberFingerprints per user
disable_facenumberDisable face
enable_palmnumberEnable palm

##### Serial & Network Settings

FieldTypeDescription
usedcomnumberSerial port in use
combauratenumberSerial baud rate
netipaddressIPEthernet IP address
netmaskIPSubnet mask
netgatewayIPGateway
use_eth_dhcpnumberUse Ethernet DHCP
commpasswordnumberCommunication password
netportnumnumberNetwork port number
rs485_funnumberRS485 function
use_wlannumberUse WiFi
use_wlan_dhcpnumberUse WiFi DHCP
wlan_ip_addressIPWiFi IP address
wlan_net_maskIPWiFi subnet mask
wlan_gatewayIPWiFi gateway
wlan_ssidstringWiFi SSID
wlan_pwdstringWiFi password
gprs_apnstringGPRS APN
gps_durationnumberGPS report interval
gprs_ipaddressnumberGPRS IP address
gprs_macaddressnumberGPRS MAC address

##### Server Settings

FieldTypeDescription
serveripIPServer IP address
serverportnumberServer port
webserverportnumberWeb server port
server_response_timenumberServer response timeout
user_add_enablenumberAllow adding users
use_bsnumberUse backend service
use_webservernumberUse web server
bs_domain_namestringBackend service domain name
use_domain_namenumberUse domain name
dns_server_ipIPDNS server IP
server_dns_namestringServer domain name
server_verifynumberServer verification mode
server_verify_timeoutnumberServer verification timeout
use_ntpnumberUse NTP
ntp_timezonenumberNTP timezone

##### Door Access Settings

FieldTypeDescription
door_opentimenumberDoor open time (seconds)
door_sensor_typenumberDoor sensor type
door_alarm_timenumberDoor alarm time
door_firealarminnumberFire alarm input
door_interlocknumberDoor interlock
door_mutiopennumberMulti-door open
door_trycountnumberAttempt count alarm
access_timesnumberAccess times
door_antipassnumberAnti-passback
multiusersnumberMulti-user verification
door_passwordnumberDoor password
timezone_punchsnumberTimezone punch
access_denied_nolognumberAccess denied without log
outof_notimzone_deniednumberDeny out-of-timezone
elevator_controlnumberElevator control
floor_numbernumberFloor number
base_floornumberBase floor
have_g_floornumberHas G floor
elevator_keypadnumberElevator keypad
maintenance_cardnumberMaintenance card

##### Wiegand Settings

FieldTypeDescription
wiegand_output_modenumberWiegand output mode
card_disp_formatnumberCard display format
card_reversalnumberCard reversal
wg_reversalnumberWiegand reversal
wiegand_output_bitnumberWiegand output bits
wiegand_outside_inputnumberWiegand outside input
alarm_outputnumberAlarm output
outwg_shotnumberWiegand output trigger
wiegand_portnumberWiegand port

##### Card & Security Settings

FieldTypeDescription
bio_to_cardnumberBiometric to card number
bio_verify_waivernumberBiometric verify waiver
bio_deletionnumberBiometric deletion
bio_user_deletionnumberUser biometric deletion
cpucard_keystringCPU card key
qrcode_pwdstringQR code password
webserver_pwdstringWeb server password

##### Other Settings

FieldTypeDescription
threatnumberThreat level
hide_ipnumberHide IP display
key_locknumberKey lock
face_wakeup_secondsnumberFace wake-up time (seconds)
Type Notes: number = numeric, IP = IP address string (e.g. "192.168.1.100"), string = plain string.

7.1.6 `setdevinfo` — Set Device Configuration Parameters

Request:

JSON{
  "cmd": "setdevinfo",
  "password": "xxx",
  "nowtime": 1700000000,
  "deviceid": 1,
  "volume": 80,
  "live_detect": 1,
  "fcmatch_level": 60
}
FieldTypeRequiredDescription
nowtimenumberNoUnix timestamp (seconds) for time sync
Other fields-NoAny DI_* configuration key-value pairs; only include items you want to modify
Type Rules:
- IP-type fields (e.g. netipaddress, serverip, etc.) accept IP address strings like "192.168.1.100"
- String-type fields (e.g. wlan_ssid, excel_password, cpucard_key, etc.) accept string values
- All other fields are numeric and accept numbers

7.1.7 `getdevcap` — Get Device Capacity Info

Request:

JSON{ "cmd": "getdevcap", "password": "xxx" }

Response:

JSON{
  "ret": "getdevcap",
  "sn": "SN123456",
  "result": true,
  "usersize": 10000,
  "facesize": 10000,
  "avatarsize": 10000,
  "fpsize": 30000,
  "palmsize": 30000,
  "cardsize": 10000,
  "pwdsize": 10000,
  "logsize": 100000,
  "useduser": 150,
  "usedface": 148,
  "usedavatar": 100,
  "usedfp": 10,
  "usedpalm": 0,
  "usedcard": 50,
  "usedpwd": 20,
  "usedlog": 5000,
  "usednewlog": 100,
  "usedrtlog": 5
}
FieldTypeDescription
usersizenumberMax user capacity
facesizenumberMax face enrollment capacity
avatarsizenumberMax avatar capacity
fpsizenumberMax fingerprint capacity
palmsizenumberMax palm print capacity
cardsizenumberMax card capacity
pwdsizenumberMax password capacity
logsizenumberMax log capacity
usedusernumberCurrent enrolled user count
usedfacenumberCurrent enrolled face count
usedavatarnumberCurrent enrolled avatar count
usedfpnumberCurrent enrolled fingerprint count
usedpalmnumberCurrent enrolled palm print count
usedcardnumberCurrent enrolled card count
usedpwdnumberCurrent enrolled password count
usedlognumberTotal log count
usednewlognumberNew (unread) log count
usedrtlognumberReal-time log count

7.2 User Management


7.2.1 `getuserlist` — Get User List (Paginated)

Request:

JSON{
  "cmd": "getuserlist",
  "password": "xxx",
  "stn": 1
}
FieldTypeDescription
stnnumber1 = start from beginning; 0 = continue to next page

Response:

JSON{
  "ret": "getuserlist",
  "sn": "SN123456",
  "result": true,
  "count": 100,
  "to": 50,
  "record": [
    {
      "id": "1001",
      "name": "John Doe",
      "department": "Engineering",
      "shift": 0,
      "admin": 0,
      "fingerprint": 2,
      "palm": 0,
      "face": 1,
      "password": 0,
      "card": 12345678,
      "weekzone": 0,
      "group": 0,
      "access_times": 0,
      "verifymode": 0,
      "enable": 1,
      "birthday": "01-15",
      "starttime": "2024-01-01 00: 00",
      "endtime": "2025-12-31 23: 59",
      "photourl": "/photos/LF00001001.jpg"
    }
  ]
}
FieldTypeDescription
countnumberTotal user count
tonumberNumber of records returned (0 if no more data)
record[]arrayArray of user objects (max 50 per page)
record[].idstringUser ID
record[].namestringUser name
record[].departmentstringDepartment
record[].shiftnumberShift ID
record[].adminnumberAdmin flag (0=user, 1=admin)
record[].fingerprintnumberEnrolled fingerprint count
record[].palmnumberEnrolled palm print count
record[].facenumberEnrolled face count
record[].passwordnumberPassword set flag
record[].cardnumberCard ID
record[].weekzonenumberWeek zone ID
record[].groupnumberGroup ID
record[].access_timesnumberAllowed access times
record[].verifymodenumberVerification mode (see Appendix 10)
record[].enablenumberEnable flag (1=enabled, 0=disabled)
record[].birthdaystringBirthday "MM-DD" (append * for lunar)
record[].starttimestringValid start time
record[].endtimestringValid end time
record[].photourlstringPhoto URL (if available)
record[].userprofilestringUser profile string (conditional)
Returns up to 50 records per call. Call repeatedly with stn=0 until to >= count or to == 0.

7.2.2 `getuserids` — Get All User IDs

Request:

JSON{ "cmd": "getuserids", "password": "xxx" }

Response:

JSON{
  "ret": "getuserids",
  "sn": "SN123456",
  "result": true,
  "count": 3,
  "record": ["1001", "1002", "1003"]
}
FieldTypeDescription
countnumberTotal user count
recordarrayArray of user ID strings

7.2.3 `getunuserdid` — Get Next Available User ID

Request:

JSON{ "cmd": "getunuserdid", "password": "xxx" }

Response:

JSON{
  "ret": "getunuserdid",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1004"
}
FieldTypeDescription
enrollidstringNext unused user ID

7.2.4 `checkuserid` — Check If User ID Exists

Request:

JSON{
  "cmd": "checkuserid",
  "password": "xxx",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstring/numberUser ID to check

Response:

JSON{
  "ret": "checkuserid",
  "sn": "SN123456",
  "result": true,
  "exists": true
}
FieldTypeDescription
existsboolWhether the user ID exists

7.2.5 `getuserinfo` — Get Single User Details

Request:

JSON{
  "cmd": "getuserinfo",
  "password": "xxx",
  "enrollid": "1001",
  "backupnum": 50
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID
backupnumnumberOptional — retrieve specific biometric data (see Appendix)

Response (with face photo, backupnum=50):

JSON{
  "ret": "getuserinfo",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001",
  "name": "John Doe",
  "department": "Engineering",
  "admin": 0,
  "pwd": 0,
  "card": 12345678,
  "fpflag": 3,
  "fpcnt": 2,
  "palmflag": 1,
  "palmcnt": 1,
  "faceflag": 1,
  "birthday": "01-15",
  "starttime": "2024-01-01 00: 00: 00",
  "endtime": "2025-12-31 23: 59: 59",
  "photourl": "/photos/LF00001001.jpg",
  "backupnum": 50,
  "record": "<Base64-encoded face photo>"
}

Response (user not found):

JSON{
  "ret": "getuserinfo",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "can not find the user",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstringUser ID
namestringUser name
departmentstringDepartment
adminnumberAdmin flag
pwdnumberPassword flag
cardnumberCard ID (conditional)
fpflagnumberFingerprint flag bitmask (conditional)
fpcntnumberEnrolled fingerprint count (conditional)
palmflagnumberPalm print flag (conditional)
palmcntnumberEnrolled palm print count (conditional)
faceflagnumberFace flag (conditional)
enablenumberUser enabled flag (conditional)
birthdaystringBirthday "MM-DD" (conditional)
shiftidnumberShift ID (conditional)
verifymodenumberVerification mode (conditional; see Appendix 10)
zoneidnumberTime zone ID (conditional)
groupidnumberGroup ID (conditional)
access_timesnumberAllowed access times (conditional)
postidnumberDepartment/post ID (conditional)
starttimestringValid start time (conditional)
endtimestringValid end time (conditional)
userprofilestringUser profile string (conditional)
backupnumnumberRequested backupnum (conditional)
recordstringBase64 biometric data (conditional, varies by backupnum)
photourlstringPhoto URL (conditional)

record format by backupnum:

backupnumrecord formatDescription
0–9stringFingerprint template — hex with zero run-length compression ((N) = N consecutive 0x00 bytes), 810 bytes after decoding. Omitted when the slot is empty.
10numberUser password
11numberCard number
40 / 41stringPalm vein template — Base64, 1548 bytes after decoding
50stringFace JPEG photo — Base64
51stringFace feature + key points — Base64, 1074 bytes after decoding (2-byte header + 1072-byte feature)
An exported record can be pushed verbatim to another device with setuserinfo (using the same backupnum) to migrate biometric templates.

7.2.6 `setuserinfo` — Add or Update User Information

Request:

JSON{
  "cmd": "setuserinfo",
  "password": "xxx",
  "enrollid": "1001",
  "name": "John Doe",
  "admin": 0,
  "pwd": 123456,
  "card": 12345678,
  "department": "Engineering",
  "birthday": "01-15",
  "starttime": "2024-01-01 00: 00: 00",
  "endtime": "2025-12-31 23: 59: 59",
  "verifymode": 0,
  "shiftid": 1,
  "zoneid": 1,
  "groupid": 0,
  "access_times": 0,
  "enable": 1,
  "face": "<Base64-encoded face photo>"
}
FieldTypeDescription
enrollidstring/numberUser ID (string or number)
namestringFull name
adminnumberPrivilege: 0=regular user, 1=administrator
pwdnumberPassword (numeric)
cardnumber/stringRFID card ID
departmentstringDepartment name (auto-created if not found)
postidnumberDepartment/post ID
birthdaystringBirthday in MM-DD format (append * for lunar calendar)
starttimestringValid start datetime YYYY-MM-DD HH:MM:SS
endtimestringValid end datetime YYYY-MM-DD HH:MM:SS
verifymodenumberUser verification mode (0 = any method; see Appendix 10)
shiftidnumberShift ID
zoneidnumberTime zone ID
groupidnumberGroup ID
access_timesnumberAllowed pass count (0=unlimited, max 30000)
enablenumberUser enabled: 0/1
facestringBase64-encoded face image (JPEG, ≤512KB)
backupnumnumberBiometric slot index (see Appendix 9)
recordstringBiometric template data; encoding depends on backupnum (see below)
userprofilestringUser profile string

How each biometric type is pushed:

BiometricbackupnumData fieldrecord encodingLength after decoding
Face photoomitted (or 50)faceBase64 (JPEG)≤ 512KB
Fingerprint0–9 (finger index)recordHex + zero run-length compression (not Base64)810 bytes
Palm vein / palm print40 = left, 41 = rightrecordBase641548 bytes
Face feature + key points51recordBase641074 bytes (2-byte header + 1072-byte feature)
⚠️ The fingerprint record is not Base64 — it is a "hex + zero run-length" text string. Only palm vein and face feature use Base64. The decoded length must match the table exactly, otherwise the device replies "xxx data error".

record encoding rules:

backupnumEncoding rule
0–9 fingerprintEach byte as 2 lowercase hex digits; runs of N 0x00 bytes are compressed to (N). E.g. 00 00 00 → (3), and bytes 0a 1f 00 00 2b → 0a1f(2)2b. Must decode to exactly 810 bytes.
40 / 41 palm veinStandard Base64, must decode to exactly 1548 bytes (Base64 string is always 2064 characters).
51 face featureStandard Base64, must decode to exactly 1074 bytes: 2-byte template header (08 06 on regular platforms, 08 10 on BOARD_CORE_810) followed by the 1072-byte feature vector, which already contains 10 float face key points and the normalization parameters.
50 face photoReturned as Base64 JPEG by getuserinfo only; push photos with the face field.

Recommended call order: create the user first with a setuserinfo call that carries no biometric data, then push each template by backupnum. Pushing backupnum=51 for a non-existent user fails with "face error".

Response (success):

JSON{
  "ret": "setuserinfo",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001",
  "backupnum": 50
}

Response (failure):

JSON{
  "ret": "setuserinfo",
  "sn": "SN123456",
  "result": false,
  "reason": 5,
  "msg": "no face",
  "enrollid": "1001"
}

Face enrollment failure reason codes:

reasonDescription
1Image file too large
5No face detected
6Multiple faces detected
7Image dimensions too large
8Face region too large
9Face region too small
10Image quality too low
11Face position too off-center
12Duplicate face (already registered to another user ID, e.g. face is double,id=1002)

Example 1 — push a face photo (face field, device extracts the feature on site):

JSON{
  "cmd": "setuserinfo",
  "password": "xxx",
  "enrollid": "1001",
  "name": "John Doe",
  "face": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL..."
}
JSON{
  "ret": "setuserinfo",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

Example 2 — push a fingerprint (slot 0, backupnum=0, record is the compressed hex string):

JSON{
  "cmd": "setuserinfo",
  "password": "xxx",
  "enrollid": "1001",
  "backupnum": 0,
  "record": "0a1f2b(807)"
}
The sample above is a complete, format-valid payload: 3 hex bytes followed by (807) (807 0x00 bytes), which decodes to exactly 810 bytes. Minimal testable payload: "record": "(810)", which decodes to 810 0x00 bytes and passes format validation. To push a real template, export the same encoding from an enrolled device with getuserinfo (backupnum=0) or bioread.

Example 3 — push a palm vein template (left hand, backupnum=40; right hand is 41):

JSON{
  "cmd": "setuserinfo",
  "password": "xxx",
  "enrollid": "1001",
  "backupnum": 40,
  "record": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
}
record is standard Base64 and must decode to exactly 1548 bytes (the Base64 string is always 2064 characters). Minimal testable payload: Base64 of 1548 0x00 bytes (2064 A characters).

Example 4 — push a face feature with key points (backupnum=51, record is Base64):

JSON{
  "cmd": "setuserinfo",
  "password": "xxx",
  "enrollid": "1001",
  "backupnum": 51,
  "record": "CAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
}
record is standard Base64 and must decode to exactly 1074 bytes. Minimal testable payload: 08 06 + 1072 0x00 bytes, i.e. a Base64 string starting with CAYA followed by 1428 A characters (1432 characters in total); on BOARD_CORE_810 use the 08 10 header instead (Base64 starts with CBAA). Export real features from an enrolled device with getuserinfo (backupnum=51) and feed them back to other devices unchanged.

Response (success):

JSON{
  "ret": "setuserinfo",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001",
  "backupnum": 51
}
The response echoes backupnum whenever it was present in the request.

Response (failures):

JSON{
  "ret": "setuserinfo",
  "sn": "SN123456",
  "result": false,
  "reason": 12,
  "msg": "finger already used,id=1002",
  "finger": 0,
  "enrollid": "1001",
  "backupnum": 0
}
JSON{
  "ret": "setuserinfo",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "palm data error",
  "palm": 0,
  "enrollid": "1001",
  "backupnum": 40
}
reasonmsgDescription
1space overflowFace or fingerprint database is full
1base64 wrongface field failed Base64 decoding
3file size=0Image byte count is 0
1record can not emptybackupnum 0–9 but record is missing
1finger data errorFingerprint string is malformed or does not decode to 810 bytes
1palm data errorPalm vein Base64 is malformed or does not decode to 1548 bytes
1palm save failedPalm vein could not be written to the device
1face errorFace feature could not be written (user missing or feature DB full)
12finger already used,id=xxxFingerprint duplicated with another user (response carries finger)
12palm already used,id=xxxPalm vein duplicated with another user (response carries palm)
12face is double,id=xxxFace duplicated with another user
12card already used,id=xxxCard number already owned by another user (response carries card)
5/6/7/8/9/10/11see table aboveFace photo extraction failed on device
The reason=12 duplicate checks (face / fingerprint / palm vein / card) are controlled by the device duplicate-check switch; when it is off, no check is made and the data overwrites the existing entry.

7.2.7 `deleteuser` — Delete User or Specific Biometric Data

Request:

JSON{
  "cmd": "deleteuser",
  "password": "xxx",
  "enrollid": "1001",
  "backupnum": 12
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID
backupnumnumberAction type (see table below)
backupnumAction
12 or 13Delete entire user
0-9Delete fingerprint at specified index
10Clear password
11Clear card
40/41Delete left/right palm print
50 or 51Delete face

Response:

JSON{
  "ret": "deleteuser",
  "sn": "SN123456",
  "result": true,
  "backupnum": 12,
  "enrollid": "1001"
}
FieldTypeDescription
backupnumnumberEchoed backupnum value
enrollidstringUser ID

7.2.8 `deleteuserface` — Delete User Face

Request:

JSON{
  "cmd": "deleteuserface",
  "password": "xxx",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID

Response:

JSON{
  "ret": "deleteuserface",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

7.2.9 `deleteuserfp` — Delete All User Fingerprints

Request:

JSON{
  "cmd": "deleteuserfp",
  "password": "xxx",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID

Response:

JSON{
  "ret": "deleteuserfp",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

7.2.10 `deleteuserpalm` — Delete All User Palm Prints

Request:

JSON{
  "cmd": "deleteuserpalm",
  "password": "xxx",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID

Response:

JSON{
  "ret": "deleteuserpalm",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

7.2.11 `deleteusers` — Batch Delete Users

Request:

JSON{
  "cmd": "deleteusers",
  "password": "xxx",
  "list": ["1001", "1002", "1003"]
}
FieldTypeDescription
listarrayArray of user IDs (string or number) to delete

Response:

JSON{
  "ret": "deleteusers",
  "sn": "SN123456",
  "result": true
}

7.2.12 `cleanuser` — Delete All Users

Request:

JSON{ "cmd": "cleanuser", "password": "xxx" }
⚠️ DESTRUCTIVE: Removes all enrolled users from the device.

Response:

JSON{
  "ret": "cleanuser",
  "sn": "SN123456",
  "result": true
}

7.2.13 `enableuser` — Enable or Disable a User

Request:

JSON{
  "cmd": "enableuser",
  "password": "xxx",
  "enrollid": "1001",
  "enflag": 1
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID
enflagnumber1=enable, 0=disable (default: 1)

Response:

JSON{
  "ret": "enableuser",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

7.3 Biometric Enrollment (Device-Side)


7.3.1 `adduser` — Trigger On-Device Biometric Enrollment

Triggers the device's local screen to perform fingerprint/palm/face enrollment.

Request:

JSON{
  "cmd": "adduser",
  "password": "xxx",
  "enrollid": "1001",
  "name": "John Doe",
  "admin": 0,
  "backupnum": 50,
  "flag": 0
}
FieldTypeDescription
cancelboolSet to true to cancel current enrollment
enrollidstring/numberUser ID
backupnumnumberEnrollment type (see Appendix)
adminnumberWhether to enroll as administrator
flagnumberFlag bits
namestringUser name

Response (success):

JSON{
  "ret": "adduser",
  "sn": "SN123456",
  "result": true,
  "backupnum": 50,
  "enrollid": "1001"
}

Response (cancel):

JSON{
  "ret": "adduser",
  "result": true,
  "cancel": true
}

Response (failure):

JSON{
  "ret": "adduser",
  "sn": "SN123456",
  "result": false,
  "reason": 3,
  "msg": "device busy",
  "backupnum": 50,
  "enrollid": "1001"
}

Failure reason codes:

reasonDescription
1Empty user ID
2Invalid backupnum
3Device busy (enrollment already in progress)

7.3.2 `checkregstatus` — Query Enrollment Status

Request:

JSON{ "cmd": "checkregstatus", "password": "xxx" }

Response:

JSON{
  "ret": "checkregstatus",
  "sn": "SN123456",
  "result": true,
  "status": 1,
  "msg": "success",
  "image": "<Base64-encoded preview image>"
}
FieldTypeDescription
statusnumberEnrollment status code (see table below)
msgstringOne-time status message (cleared after read)
imagestringBase64 preview image (conditional)
statusDescription
-1Idle / cancelled
0Enrollment in progress
1Enrollment succeeded
otherEnrollment failed

7.4 Log Management


7.4.1 `getlog` — Get Historical Logs (Paginated)

Request:

JSON{
  "cmd": "getlog",
  "password": "xxx",
  "index": 0,
  "enrollid": "1001",
  "from": "2024-06-01",
  "to": "2024-12-31"
}
FieldTypeDescription
indexnumberStart position (0 = begin new query)
enrollidstring/numberOptional — filter by specific user (only when index=0)
fromstringOptional — start date YYYY-MM-DD format
tostringOptional — end date YYYY-MM-DD format

Response (up to 50 records per page):

JSON{
  "ret": "getlog",
  "sn": "SN123456",
  "result": true,
  "count": 500,
  "from": 0,
  "to": 50,
  "record": [
    {
      "enrollid": "1001",
      "name": "John Doe",
      "time": "2024-06-01 09: 00: 00",
      "mode": 1,
      "inout": 1,
      "event": 0,
      "note": "remark",
      "photourl": "/logphotos/logimage123.jpg"
    }
  ]
}
FieldTypeDescription
countnumberTotal matching log count
fromnumberStart index of returned records
tonumberEnd index of returned records
record[]arrayLog record array (max 50 per page)
record[].enrollidstringUser ID
record[].namestringUser name
record[].timestringTimestamp
record[].modenumberVerification method (1=face, 2=fingerprint, 3=card, 4=password, etc.)
record[].inoutnumberDirection: 1=entry, 0=exit
record[].eventnumberEvent type code
record[].notestring/objectRemark or additional note (conditional)
record[].photourlstringSnapshot photo URL (conditional)
Call repeatedly with incrementing index until to >= count.

7.4.2 `getrtlog` — Get Real-Time Logs (Consumed on Read)

Request:

JSON{ "cmd": "getrtlog", "password": "xxx", "index": 0 }
FieldTypeDescription
indexnumberStart position (0 = begin new query)

Response:

JSON{
  "ret": "getrtlog",
  "sn": "SN123456",
  "result": true,
  "count": 25,
  "from": 0,
  "to": 20,
  "record": [
    {
      "enrollid": "1001",
      "name": "John Doe",
      "time": "2024-06-01 09: 00: 00",
      "mode": 1,
      "inout": 1,
      "event": 0,
      "note": "remark"
    }
  ]
}
FieldTypeDescription
countnumberTotal real-time log count in queue
fromnumberStart index
tonumberEnd index
record[]arrayLog record array (max 20 per page), same fields as getlog
Real-time logs are removed from the queue once read. Up to 20 records per page. Call repeatedly with incrementing index until to >= count.

7.4.3 `setlogs` — Mark Logs as Synced

Request:

JSON{
  "cmd": "setlogs",
  "password": "xxx",
  "records": [
    { "id": "1001", "event": 0, "mode": 1, "time": "2024-06-01 09: 00: 00" }
  ]
}
FieldTypeDescription
recordsarrayArray of log records to mark as synced
records[].idstring/numberUser ID
records[].eventnumberEvent type
records[].modenumberVerification mode
records[].timestringLog timestamp

Response:

JSON{
  "ret": "setlogs",
  "sn": "SN123456",
  "result": true
}

7.4.4 `cleanlog` — Clear All Logs

Request:

JSON{ "cmd": "cleanlog", "password": "xxx" }
⚠️ DESTRUCTIVE: Removes all historical attendance logs.

Response:

JSON{
  "ret": "cleanlog",
  "sn": "SN123456",
  "result": true
}

7.4.5 `cleanlogphoto` — Clear All Log Photos

Request:

JSON{ "cmd": "cleanlogphoto", "password": "xxx" }

Response:

JSON{
  "ret": "cleanlogphoto",
  "sn": "SN123456",
  "result": true
}

7.5 System Management


7.5.1 `gettime` — Get Device Time

Request:

JSON{ "cmd": "gettime", "password": "xxx" }

Response:

JSON{
  "ret": "gettime",
  "sn": "SN123456",
  "time": "2024-06-01 10: 00: 00"
}
FieldTypeDescription
timestringCurrent device time

7.5.2 `settime` — Set Device Time

Method 1 (string format):

JSON{
  "cmd": "settime",
  "password": "xxx",
  "cloudtime": "2024-06-01 10: 00: 00"
}

Method 2 (Unix timestamp in seconds):

JSON{
  "cmd": "settime",
  "password": "xxx",
  "nowtime": 1717200000
}
FieldTypeDescription
cloudtimestringTime string in YYYY-MM-DD HH:MM:SS format (use this or nowtime)
nowtimenumberUnix timestamp in seconds (use this or cloudtime)

Response (success):

JSON{
  "ret": "settime",
  "sn": "SN123456",
  "result": true
}

Response (failure):

JSON{
  "ret": "settime",
  "sn": "SN123456",
  "result": false,
  "reason": 1
}
Validates year >= 2021, month 1-12, day, hour, minute, second ranges. Returns reason 1 on failure.

7.5.3 `reboot` — Reboot Device

Request:

JSON{ "cmd": "reboot", "password": "xxx" }
⚠️ No response — the device reboots immediately. The HTTP connection will be dropped.

7.5.4 `disabledevice` — Disable Device (Pause Recognition)

Request:

JSON{ "cmd": "disabledevice", "password": "xxx" }

Response:

JSON{
  "ret": "disabledevice",
  "sn": "SN123456",
  "result": true
}
The response is sent first, then the device disables face/fingerprint/palm/ID card recognition.

7.5.5 `enabledevice` — Enable Device (Resume Recognition)

Request:

JSON{ "cmd": "enabledevice", "password": "xxx" }

Response:

JSON{
  "ret": "enabledevice",
  "sn": "SN123456",
  "result": true
}

7.5.6 `initsys` — Full System Initialization (Clear All Data)

⚠️ DESTRUCTIVE: Clears all users, logs, and settings (language setting is preserved). Also removes bell schedules, post data, attendance settings, and lock data. Backs up WiFi configuration.

Request:

JSON{ "cmd": "initsys", "password": "xxx" }

Response:

JSON{
  "ret": "initsys",
  "sn": "SN123456",
  "result": true
}

7.5.7 `initmenu` — Reset Menu Settings (Preserve User Data)

Request:

JSON{ "cmd": "initmenu", "password": "xxx" }

Response:

JSON{
  "ret": "initmenu",
  "sn": "SN123456",
  "result": true
}
Same as initsys but does NOT clear user database or log database.

7.5.8 `cleandatebase` — Clear Log Database

Request:

JSON{ "cmd": "cleandatebase", "password": "xxx" }
⚠️ DESTRUCTIVE: Clears entire database and sets a reboot flag. Device will reboot after this operation.

Response:

JSON{
  "ret": "cleandatebase",
  "sn": "SN123456",
  "result": true
}

7.5.9 `cleanadmin` — Remove All Administrator Privileges

Request:

JSON{ "cmd": "cleanadmin", "password": "xxx" }

Response:

JSON{
  "ret": "cleanadmin",
  "sn": "SN123456",
  "result": true
}

7.5.10 `cleaninactiveuser` — Remove Users Without Biometric Data

Request:

JSON{ "cmd": "cleaninactiveuser", "password": "xxx" }

Response:

JSON{
  "ret": "cleaninactiveuser",
  "sn": "SN123456",
  "result": true
}

7.5.11 `setscreensaver` — Set Screensaver Parameters

Request:

JSON{
  "cmd": "setscreensaver",
  "password": "xxx",
  "filename": "logo.jpg",
  "photo": "<Base64-encoded image>",
  "duration": 60,
  "remove": false,
  "removeall": false
}
FieldTypeDescription
filenamestringScreensaver image filename
photostringBase64-encoded image content
durationnumberDisplay duration (seconds)
removeboolRemove specific screensaver image
removeallboolRemove all screensaver images

Response:

JSON{
  "ret": "setscreensaver",
  "sn": "SN123456",
  "result": true
}

7.5.12 `upgrade` — Trigger OTA Firmware Upgrade via JSON API

Request:

JSON{
  "cmd": "upgrade",
  "password": "xxx",
  "filename": "ai230_product.zip",
  "md5": "d41d8cd98f00b204e9800998ecf8427e",
  "allcount": 100,
  "index": 0,
  "count": 50,
  "record": "<Base64-encoded firmware chunk>"
}
FieldTypeDescription
filenamestringFirmware filename (must match device model, .zip or .pkg)
md5stringFull file MD5 checksum (verified on last chunk)
allcountnumberTotal number of chunks
indexnumberCurrent chunk index (0-based)
countnumberNumber of chunks in this request
recordstringBase64-encoded firmware data chunk

Response (success):

JSON{
  "ret": "upgrade",
  "sn": "SN123456",
  "result": true
}

Response (failure):

JSON{
  "ret": "upgrade",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "file mismatch or insufficient space"
}

Failure reason codes:

reasonDescription
1File mismatch or insufficient disk space
2MD5 checksum verification failed
3File move error
4Wrong file extension (must be .zip or .pkg)

7.5.13 `setvoice` — Configure Voice Prompts

Request:

JSON{
  "cmd": "setvoice",
  "password": "xxx",
  "index": 0,
  "voice": "<Base64-encoded WAV audio>",
  "play": true
}
FieldTypeDescription
indexnumberVoice prompt index
voicestringBase64-encoded WAV audio data (max 512KB)
playboolPlay the voice prompt immediately after setting

Response:

JSON{
  "ret": "setvoice",
  "sn": "SN123456",
  "result": true
}

7.5.14 `keypad` — Activate/Deactivate Keypad Mode

Request:

JSON{
  "cmd": "keypad",
  "password": "xxx",
  "password": true,
  "keep": false,
  "timeout": 30,
  "on": true
}
FieldTypeDescription
passwordboolEnable keypad password input
keepboolKeep keypad active after use
timeoutnumberKeypad timeout (seconds)
onboolTurn keypad on/off

Response:

JSON{
  "ret": "keypad",
  "sn": "SN123456",
  "result": true
}

7.6 Door Access Control


7.6.1 `opendoor` — Remote Door Open

Request:

JSON{
  "cmd": "opendoor",
  "password": "xxx",
  "enrollid": "1001",
  "floor": 3,
  "msg": "Welcome"
}
FieldTypeDescription
enrollidstring/numberOptional — associated user ID (for Wiegand output)
floornumberOptional — elevator control floor number
msgstringOptional — message to display on screen (for 3 seconds)

Response:

JSON{
  "ret": "opendoor",
  "sn": "SN123456",
  "result": true
}

7.6.2 `lockctrl` — Door Lock State Control

Request:

JSON{
  "cmd": "lockctrl",
  "password": "xxx",
  "fuc": 1
}
FieldTypeDescription
fucnumberLock control function code
fucDescription
1Normally Open (NO)
2Normally Closed (NC)
0Restore normal operation

Response:

JSON{
  "ret": "lockctrl",
  "sn": "SN123456",
  "result": true
}

7.6.3 `getdoorstatus` — Get Door Status

Request:

JSON{ "cmd": "getdoorstatus", "password": "xxx" }

Response:

JSON{
  "ret": "getdoorstatus",
  "sn": "SN123456",
  "result": true,
  "doorstatus": 1
}
FieldTypeDescription
doorstatusnumberCurrent door status code

7.6.4 `setdevlock` — Configure Door Access Parameters

Request (all fields optional):

JSON{
  "cmd": "setdevlock",
  "password": "xxx",
  "opendelay": 5,
  "doorsensor": 1,
  "alarmdelay": 30,
  "InputAlarm": 0,
  "antpass": 0,
  "interlock": 0,
  "mutiopen": 0,
  "tryalarm": 5,
  "access_times": 0,
  "punchtimes": 0,
  "tamper": 0,
  "wgformat": 26,
  "wgoutput": 0,
  "cardformat": 0,
  "dayzone": [],
  "weekzone": [],
  "lockgroup": [],
  "nopentime": [],
  "visitortime": []
}
FieldTypeDescription
opendelaynumberDoor open delay (seconds)
doorsensornumberDoor sensor type
alarmdelaynumberAlarm delay (seconds)
InputAlarmnumberInput alarm setting
antpassnumberAnti-passback mode
interlocknumberInterlock function
mutiopennumberMulti-user door open
tryalarmnumberFailed verification alarm threshold
access_timesnumberAccess times limit
punchtimesnumberPunch times limit
tampernumberTamper alarm setting
wgformatnumberWiegand format: 0=26bit, 1=34bit, 2=42bit, 3=50bit, 4=58bit, 5=66bit, 6=37bit
wgoutputnumberWiegand output mode
cardformatnumberCard format
dayzonearrayDay time zone schedule array
weekzonearrayWeek time zone schedule array
lockgrouparrayLock group array
nopentimearrayNo-open time array
visitortimearrayVisitor time array

Response:

JSON{
  "ret": "setdevlock",
  "sn": "SN123456",
  "result": true
}

7.6.5 `getdevlock` — Get Door Access Parameters

Request:

JSON{ "cmd": "getdevlock", "password": "xxx" }

Response:

JSON{
  "ret": "getdevlock",
  "sn": "SN123456",
  "result": true,
  "opendelay": 5,
  "doorsensor": 1,
  "alarmdelay": 30,
  "InputAlarm": 0,
  "antpass": 0,
  "interlock": 0,
  "mutiopen": 0,
  "tryalarm": 5,
  "access_times": 0,
  "tamper": 0,
  "wgformat": 26,
  "wgoutput": 0,
  "cardformat": 0,
  "dayzone": [],
  "weekzone": [],
  "lockgroup": [],
  "nopentime": [],
  "visitortime": []
}
FieldTypeDescription
opendelaynumberDoor open delay (seconds)
doorsensornumberDoor sensor type
alarmdelaynumberAlarm delay (seconds)
InputAlarmnumberInput alarm setting
antpassnumberAnti-passback mode
interlocknumberInterlock function
mutiopennumberMulti-user door open
tryalarmnumberFailed verification alarm threshold
access_timesnumberAccess times limit
tampernumberTamper alarm setting
wgformatnumberWiegand format: 0=26bit, 1=34bit, 2=42bit, 3=50bit, 4=58bit, 5=66bit, 6=37bit
wgoutputnumberWiegand output mode
cardformatnumberCard format
dayzonearrayDay time zone schedule
weekzonearrayWeek time zone schedule
lockgrouparrayLock group settings
nopentimearrayNo-open time schedule
visitortimearrayVisitor time schedule

7.6.6 `getuserlock` — Get User-Level Access Settings

Request:

JSON{
  "cmd": "getuserlock",
  "password": "xxx",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID

Response (found):

JSON{
  "ret": "getuserlock",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001",
  "birthday": "01-15",
  "verifymode": 0,
  "enable": 1,
  "weekzone": 0,
  "group": 0,
  "access_times": 0,
  "starttime": "2024-01-01 00: 00: 00",
  "endtime": "2025-12-31 23: 59: 59"
}

Response (not found):

JSON{
  "ret": "getuserlock",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "can not find the user",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstringUser ID
birthdaystringBirthday "MM-DD" format
verifymodenumberVerification mode (see Appendix 10)
enablenumberEnable flag (1=enabled, 0=disabled)
weekzonenumberWeek zone ID
groupnumberGroup ID
access_timesnumberAllowed access times
starttimestringValid start time
endtimestringValid end time

7.6.7 `setuserlock` — Set User-Level Access Parameters (Batch)

Request:

JSON{
  "cmd": "setuserlock",
  "password": "xxx",
  "count": 2,
  "record": [
    {
      "enrollid": "1001",
      "birthday": "01-15",
      "verifymode": 0,
      "weekzone": 0,
      "group": 0,
      "access_times": 0,
      "starttime": "2024-01-01 00: 00: 00",
      "endtime": "2025-12-31 23: 59: 59"
    },
    {
      "enrollid": "1002",
      "birthday": "06-20",
      "verifymode": 1,
      "weekzone": 1,
      "group": 0,
      "access_times": 5,
      "starttime": "2024-01-01 00: 00: 00",
      "endtime": "2025-12-31 23: 59: 59"
    }
  ]
}
FieldTypeDescription
countnumberNumber of records in the array
recordarrayArray of user access settings
record[].enrollidstring/numberUser ID
record[].birthdaystringBirthday "MM-DD" format
record[].verifymodenumberVerification mode (see Appendix 10)
record[].weekzonenumberWeek zone ID
record[].groupnumberGroup ID
record[].access_timesnumberAllowed access times
record[].starttimestringValid start time
record[].endtimestringValid end time

Response (success):

JSON{
  "ret": "setuserlock",
  "sn": "SN123456",
  "result": true
}

Response (failure):

JSON{
  "ret": "setuserlock",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "setuserlock fail"
}

7.6.8 `deleteuserlock` — Delete User Access Settings

Request:

JSON{
  "cmd": "deleteuserlock",
  "password": "xxx",
  "enrollid": "1001"
}
FieldTypeDescription
enrollidstring/numberUser ID or alias ID

Response:

JSON{
  "ret": "deleteuserlock",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

7.6.9 `cleanuserlock` — Clear All User Access Settings

Request:

JSON{ "cmd": "cleanuserlock", "password": "xxx" }

Response:

JSON{
  "ret": "cleanuserlock",
  "sn": "SN123456",
  "result": true
}

7.6.10 `openallfloors` — Open All Floors

Request:

JSON{ "cmd": "openallfloors", "password": "xxx" }

Response:

JSON{
  "ret": "openallfloors",
  "sn": "SN123456",
  "result": true
}

7.6.11 `closeallfloors` — Close All Floors

Request:

JSON{ "cmd": "closeallfloors", "password": "xxx" }

Response:

JSON{
  "ret": "closeallfloors",
  "sn": "SN123456",
  "result": true
}

7.6.12 `openselectfloors` — Open Selected Floors

Request:

JSON{
  "cmd": "openselectfloors",
  "password": "xxx",
  "profile": "1,2,5"
}
FieldTypeDescription
profilestringComma-separated floor numbers to open (optional)

Response:

JSON{
  "ret": "openselectfloors",
  "sn": "SN123456",
  "result": true
}

7.6.13 `closeselectfloors` — Close Selected Floors

Request:

JSON{
  "cmd": "closeselectfloors",
  "password": "xxx",
  "profile": "3,4"
}
FieldTypeDescription
profilestringComma-separated floor numbers to close (optional)

Response:

JSON{
  "ret": "closeselectfloors",
  "sn": "SN123456",
  "result": true
}

7.7 Shifts & Attendance


7.7.1 `getshift` — Get Shift Configuration

Request:

JSON{ "cmd": "getshift", "password": "xxx" }

Response:

JSON{
  "ret": "getshift",
  "sn": "SN123456",
  "result": true,
  "shifts": [
    {
      "name": "Shift 1",
      "cutoftime": 10,
      "sections": [
        { "start": "09: 00", "end": "12: 00", "type": 0 },
        { "start": "13: 00", "end": "18: 00", "type": 0 },
        { "start": "", "end": "", "type": 0 }
      ]
    }
  ]
}
FieldTypeDescription
shiftsarrayArray of up to 8 shift definitions
shifts[].namestringShift name
shifts[].cutoftimenumberCutoff time (minutes) for late arrival
shifts[].sectionsarrayArray of 3 time sections per shift
shifts[].sections[].startstringSection start time "HH:MM"
shifts[].sections[].endstringSection end time "HH:MM"
shifts[].sections[].typenumberSection type

7.7.2 `setshift` — Set Shift Configuration

Request:

JSON{
  "cmd": "setshift",
  "password": "xxx",
  "shifts": [
    {
      "name": "Shift 1",
      "cutoftime": 10,
      "sections": [
        { "start": "09: 00", "end": "12: 00", "type": 0 },
        { "start": "13: 00", "end": "18: 00", "type": 0 },
        { "start": "", "end": "", "type": 0 }
      ]
    }
  ]
}
FieldTypeDescription
shiftsarrayArray of up to 8 shift definitions
shifts[].namestringShift name
shifts[].cutoftimenumberCutoff time (minutes)
shifts[].sectionsarrayArray of 3 time sections per shift
shifts[].sections[].startstringSection start time "HH:MM"
shifts[].sections[].endstringSection end time "HH:MM"
shifts[].sections[].typenumberSection type

Response:

JSON{
  "ret": "setshift",
  "sn": "SN123456",
  "result": true
}

7.7.3 `getbelltime` — Get Bell Schedule

Request:

JSON{ "cmd": "getbelltime", "password": "xxx" }

Response:

JSON{
  "ret": "getbelltime",
  "sn": "SN123456",
  "result": true,
  "belltimes": [
    { "time": "09: 00", "flag": 1 },
    { "time": "12: 00", "flag": 0 },
    { "time": "13: 00", "flag": 1 },
    { "time": "18: 00", "flag": 0 }
  ]
}
FieldTypeDescription
belltimesarrayBell schedule array
belltimes[].timestringBell time "HH:MM"
belltimes[].flagnumberBell type flag

7.7.4 `setbelltime` — Set Bell Schedule

Request:

JSON{
  "cmd": "setbelltime",
  "password": "xxx",
  "belltimes": [
    { "time": "09: 00", "flag": 1 },
    { "time": "12: 00", "flag": 0 },
    { "time": "13: 00", "flag": 1 },
    { "time": "18: 00", "flag": 0 }
  ]
}
FieldTypeDescription
belltimesarrayBell schedule array
belltimes[].timestringBell time "HH:MM"
belltimes[].flagnumberBell type flag

Response:

JSON{
  "ret": "setbelltime",
  "sn": "SN123456",
  "result": true
}

7.7.5 `getholiday` — Get Holiday Settings

Request:

JSON{ "cmd": "getholiday", "password": "xxx" }

Response:

JSON{
  "ret": "getholiday",
  "sn": "SN123456",
  "result": true,
  "holidays": [
    {
      "name": "New Year",
      "startday": "01-01",
      "endday": "01-03",
      "shift": 0,
      "dayzone": 0
    }
  ]
}
FieldTypeDescription
holidaysarrayArray of up to 30 holiday definitions
holidays[].namestringHoliday name
holidays[].startdaystringStart date "MM-DD"
holidays[].enddaystringEnd date "MM-DD"
holidays[].shiftnumberShift ID to apply
holidays[].dayzonenumberDay zone ID

7.7.6 `setholiday` — Set Holiday Settings

Request:

JSON{
  "cmd": "setholiday",
  "password": "xxx",
  "holidays": [
    {
      "name": "New Year",
      "startday": "01-01",
      "endday": "01-03",
      "shift": 0,
      "dayzone": 0
    }
  ]
}
FieldTypeDescription
holidaysarrayArray of up to 30 holiday definitions
holidays[].namestringHoliday name
holidays[].shiftnumberShift ID to apply
holidays[].dayzonenumberDay zone ID
holidays[].startdaystringStart date "MM-DD"
holidays[].enddaystringEnd date "MM-DD"

Response:

JSON{
  "ret": "setholiday",
  "sn": "SN123456",
  "result": true
}

7.8 Reports


7.8.1 `getreport` — Get Attendance Report Data

Request:

JSON{
  "cmd": "getreport",
  "password": "xxx",
  "enrollid": "1001",
  "from": "2024-01-01",
  "to": "2024-12-31"
}
FieldTypeDescription
enrollidstring/numberOptional — filter by specific user
fromstringStart date "YYYY-MM-DD"
tostringEnd date "YYYY-MM-DD"

Response (success):

JSON{
  "ret": "getreport",
  "sn": "SN123456",
  "result": true
}

Response (no logs found):

JSON{
  "ret": "getreport",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "can not find logs"
}
Response contains dynamic report data fields depending on the report type and date range.

7.8.2 `generatereport` — Generate Report Files

Request:

JSON{
  "cmd": "generatereport",
  "password": "xxx",
  "enrollid": "1001",
  "from": "2024-01-01",
  "to": "2024-12-31"
}
FieldTypeDescription
enrollidstring/numberOptional — filter by specific user
fromstringStart date "YYYY-MM-DD"
tostringEnd date "YYYY-MM-DD"

Response (success):

JSON{
  "ret": "generatereport",
  "sn": "SN123456",
  "result": true,
  "msg": "Report generation started."
}

Response (busy):

JSON{
  "ret": "generatereport",
  "sn": "SN123456",
  "result": false,
  "reason": 3,
  "msg": "A report is already being generated. Please wait."
}
After generation completes, files can be downloaded via /download/report and /download/rawrecord.

7.8.3 `checkreportprogress` — Check Report Generation Progress

Request:

JSON{ "cmd": "checkreportprogress", "password": "xxx" }

Response (in progress):

JSON{
  "ret": "checkreportprogress",
  "sn": "SN123456",
  "result": true,
  "progress": 75,
  "status": "generating",
  "finished": false
}

Response (completed):

JSON{
  "ret": "checkreportprogress",
  "sn": "SN123456",
  "result": true,
  "progress": 100,
  "status": "completed",
  "finished": true,
  "file_exists": true
}
FieldTypeDescription
progressnumberGeneration progress percentage (0-100)
statusstringCurrent status description
finishedboolWhether generation is complete
file_existsboolWhether report file is available for download (only when finished)

7.9 Questionnaire & Notices


7.9.1 `setquestionnaire` — Configure Questionnaire

Request:

JSON{
  "cmd": "setquestionnaire",
  "password": "xxx",
  "title": "Health Declaration",
  "voice": "Please complete health declaration",
  "errmsg": "Declaration failed",
  "radio": true,
  "optionflag": 3,
  "items": ["Question 1", "Question 2"],
  "schedules": ["08: 00-09: 00", "12: 00-13: 00"],
  "usequestion": true,
  "useschedule": false,
  "card": 0,
  "switch_card": 0,
  "enrollid": "1001",
  "open": true
}
FieldTypeDescription
titlestringQuestionnaire title
voicestringVoice prompt text
errmsgstringError message text
radioboolUse radio button style (single select)
optionflagnumberOption flag
itemsarrayArray of up to 16 questionnaire items (strings)
schedulesarrayArray of up to 8 schedule strings
usequestionboolEnable questionnaire feature
usescheduleboolEnable schedule-based questionnaire
cardnumber/stringAssociated card ID
switch_cardnumber/stringSwitch card ID
enrollidstring/numberAssociated user ID
openboolOpen questionnaire for responses

Response:

JSON{
  "ret": "setquestionnaire",
  "sn": "SN123456",
  "result": true
}

7.9.2 `getquestionnaire` — Get Questionnaire Configuration

Request:

JSON{ "cmd": "getquestionnaire", "password": "xxx" }

Response (configured):

JSON{
  "ret": "getquestionnaire",
  "sn": "SN123456",
  "result": true,
  "title": "Health Declaration",
  "voice": "Please complete health declaration",
  "errmsg": "Declaration failed",
  "radio": true,
  "optionflag": 3,
  "usequestion": true,
  "useschedule": false,
  "card": 0,
  "switch_card": 0,
  "items": ["Question 1", "Question 2"],
  "schedules": ["08: 00-09: 00", "12: 00-13: 00"]
}

Response (not configured):

JSON{
  "ret": "getquestionnaire",
  "sn": "SN123456",
  "result": false
}
FieldTypeDescription
titlestringQuestionnaire title
voicestringVoice prompt text
errmsgstringError message text
radioboolRadio button mode
optionflagnumberOption flag
usequestionboolQuestionnaire enabled
usescheduleboolSchedule mode enabled
cardnumberAssociated card ID
switch_cardnumberSwitch card ID
itemsarrayQuestionnaire items
schedulesarraySchedule strings

7.9.3 `cleanquestionnaire` — Clear Questionnaire Settings

Request:

JSON{ "cmd": "cleanquestionnaire", "password": "xxx" }

Response:

JSON{
  "ret": "cleanquestionnaire",
  "sn": "SN123456",
  "result": true
}

7.9.4 `setcompanyname` — Set Company Name

Request:

JSON{
  "cmd": "setcompanyname",
  "password": "xxx",
  "name": "ACME Corporation"
}
FieldTypeDescription
namestringCompany name (max 21 characters)

Response:

JSON{
  "ret": "setcompanyname",
  "sn": "SN123456",
  "result": true
}

7.9.5 `getcompanyname` — Get Company Name

Request:

JSON{ "cmd": "getcompanyname", "password": "xxx" }

Response:

JSON{
  "ret": "getcompanyname",
  "sn": "SN123456",
  "result": true,
  "name": "ACME Corporation"
}
FieldTypeDescription
namestringCurrent company name

7.10 Video Intercom (WebRTC)


7.10.1 `enablewebrtc` — Initiate Video Call

Request:

JSON{
  "cmd": "enablewebrtc",
  "password": "xxx",
  "intercom": true,
  "monitor": true,
  "inputmode": 0,
  "waitseconds": 30,
  "stunserver": "stun:stun.l.google.com: 19302",
  "turnserver": "",
  "turnusername": "",
  "turnpassword": ""
}
FieldTypeDescription
intercomboolEnable intercom mode
monitorboolEnable monitor mode
inputmodenumberInput mode: 0=direct call (no input dialog), 1=enroll/ID number, 2=phone number, 3=room number, 4=visual selection menu
audioonlynumber / boolAudio-only intercom: 1/true = audio only, 0/false = audio + video (also controls video on/off)
waitsecondsnumberWait timeout (seconds)
stunserverstringSTUN server URL
turnserverstringTURN server URL
turnusernamestringTURN server username
turnpasswordstringTURN server password

Response (success):

JSON{
  "ret": "enablewebrtc",
  "sn": "SN123456",
  "result": true,
  "lanscape": 0
}

Response (hardware not supported):

JSON{
  "ret": "enablewebrtc",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "this device have not this function"
}
FieldTypeDescription
lanscapenumberScreen orientation (landscape flag)

7.10.2 `getwebrtc` — Get WebRTC Signaling Status

Request:

JSON{ "cmd": "getwebrtc", "password": "xxx" }

Response (success):

JSON{
  "ret": "getwebrtc",
  "sn": "SN123456",
  "result": true,
  "intercom": true,
  "monitor": false,
  "inputmode": 0,
  "waitseconds": 30,
  "stunserver": "stun:stun.l.google.com: 19302",
  "turnserver": "",
  "turnusername": "",
  "turnpassword": ""
}

Response (hardware not supported):

JSON{
  "ret": "getwebrtc",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "this device have not this function"
}
FieldTypeDescription
intercomboolIntercom enabled
monitorboolMonitor enabled
inputmodenumberAudio input mode
waitsecondsnumberWait timeout (seconds)
stunserverstringSTUN server URL
turnserverstringTURN server URL
turnusernamestringTURN server username
turnpasswordstringTURN server password

7.10.3 `checklive` — Check Live Stream Status

Request:

JSON{ "cmd": "checklive", "password": "xxx" }

Response (ICE candidate available):

JSON{
  "sn": "SN123456",
  "cmd": "icecandidate",
  "candidate": "<ICE candidate string>"
}

Response (call cancelled on device):

JSON{
  "sn": "SN123456",
  "cmd": "talkcancel"
}

Response (no activity):

(null — no response)
This command has non-standard response format. Returns ICE candidate data when available, cancellation notice if call was ended on the device side, or no response at all when idle.

7.10.4 `answer` — SDP Answer

Request:

JSON{
  "cmd": "answer",
  "password": "xxx",
  "sdp": "<SDP string>"
}
FieldTypeDescription
sdpstringSDP answer string

Response (success):

JSON{
  "ret": "answer",
  "sn": "SN123456",
  "result": true
}

Response (failure):

JSON{
  "ret": "answer",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "device error"
}

Failure reason codes:

reasonDescription
1Device error
2SDP parameter missing

7.10.5 `icecandidate` — ICE Candidate Exchange

Request:

JSON{
  "cmd": "icecandidate",
  "password": "xxx",
  "candidate": "<ICE candidate string>"
}
FieldTypeDescription
candidatestringICE candidate string

Response:

JSON{
  "ret": "icecandidate",
  "sn": "SN123456",
  "result": true
}

7.10.6 `callcancel` — Cancel Call

Request:

JSON{ "cmd": "callcancel", "password": "xxx" }

Response:

JSON{
  "ret": "callcancel",
  "sn": "SN123456",
  "result": true
}

7.10.7 `monitorcall` — Monitor Mode Call

Request:

JSON{ "cmd": "monitorcall", "password": "xxx" }

Response (offer SDP):

JSON{
  "cmd": "offer",
  "sn": "SN123456",
  "type": "offer",
  "sdp": "<SDP offer string>"
}

Response (failure):

JSON{
  "ret": "monitorcall",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "device busy"
}

Failure reason codes:

reasonDescription
1Device busy (another call in progress)
2Offer generation failed

7.11 Biometric Verification


7.11.1 `verify` — Remote Biometric Verification

Performs remote biometric verification on the device using provided biometric data.

Request:

JSON{
  "cmd": "verify",
  "password": "xxx",
  "enrollid": "1001",
  "card": "12345678",
  "pwd": 123456,
  "name": "John Doe",
  "face": "<Base64-encoded face JPEG>",
  "finger": "<Hex fingerprint template>",
  "finger2": "<Hex second fingerprint template>",
  "profile": "default"
}
FieldTypeDescription
enrollidstring/numberOptional — expected user ID for matching
cardstring/numberOptional — card number for verification
pwdnumberOptional — numeric password for verification
namestringOptional — user name
facestringOptional — Base64-encoded face image (JPEG)
fingerstringOptional — Hex-encoded fingerprint template
finger2stringOptional — Hex-encoded second fingerprint template
profilestringOptional — verification profile string

Response (success):

JSON{
  "ret": "verify",
  "sn": "SN123456",
  "result": true,
  "enrollid": "1001"
}

Response (failure):

JSON{
  "ret": "verify",
  "sn": "SN123456",
  "result": false,
  "reason": 1,
  "msg": "verification failed",
  "enrollid": "1001"
}

Failure reason codes:

reasonDescription
1User not found
2Password incorrect
3Card not found
4Fingerprint mismatch
5No face detected
6Multiple faces detected
7Image too large
8Face too large
9Face too small
10Image quality too low
11Face position off-center
12Face not matched

7.11.2 `biomatch` — Biometric Matching (OSDP Test)

Request:

JSON{ "cmd": "biomatch", "password": "xxx" }
Requires config_OSDP_TEST configuration.

Response:

JSON{
  "ret": "biomatch",
  "sn": "SN123456",
  "result": true
}

7.11.3 `bioread` — Read Raw Biometric Data (OSDP Test)

Request:

JSON{ "cmd": "bioread", "password": "xxx" }
Requires config_OSDP_TEST configuration.

Response:

JSON{
  "ret": "bioread",
  "sn": "SN123456",
  "result": true
}

7.12 File Operations


7.12.1 `getdir` — List Directory Contents

Request:

JSON{
  "cmd": "getdir",
  "password": "xxx",
  "path": "/data"
}
FieldTypeDescription
pathstringDirectory path to list

Response (success):

JSON{
  "ret": "getdir",
  "sn": "SN123456",
  "result": true,
  "files": ["config.txt", "photo.jpg", "logs/"]
}

Response (failure):

JSON{
  "ret": "getdir",
  "sn": "SN123456",
  "result": false
}
FieldTypeDescription
filesarrayArray of file/directory name strings

7.12.2 `getfile` — Get File Content (Base64 encoded)

Request:

JSON{
  "cmd": "getfile",
  "password": "xxx",
  "path": "/data/config.txt"
}
FieldTypeDescription
pathstringFile path to read

Response (success):

JSON{
  "ret": "getfile",
  "sn": "SN123456",
  "result": true,
  "base64": "<Base64-encoded file content>"
}

Response (failure):

JSON{
  "ret": "getfile",
  "sn": "SN123456",
  "result": false
}
FieldTypeDescription
base64stringBase64-encoded file content

7.12.3 `writefile` — Write File

Request:

JSON{
  "cmd": "writefile",
  "password": "xxx",
  "path": "/data/notice.txt",
  "base64": "<Base64-encoded content>"
}
FieldTypeDescription
pathstringFile path to write
base64stringBase64-encoded file content

Response (success):

JSON{
  "ret": "writefile",
  "sn": "SN123456",
  "result": true
}

Response (failure):

JSON{
  "ret": "writefile",
  "sn": "SN123456",
  "result": false
}

7.13 Firmware Upgrade

Firmware upgrades use a dedicated HTTP endpoint (not JSON API).

Endpoint: POST /api/firmware/upload

Query Parameters:

ParameterDescription
nameFirmware filename (must match device model, e.g., ai230_.zip or .pkg)
offsetCurrent chunk start offset (bytes)
totalTotal file size (bytes)
passwordDevice password
md5File MD5 checksum (verified on last chunk)

Chunked Transfer Logic:

  1. Each POST carries a file chunk as the request body
  2. offset=0 marks the first chunk — device clears /data/ota directory
  3. When data.len == 0 and offset >= total, MD5 is verified and processing completes
  4. Supported formats: .zip (system update) and .pkg (firmware package)

Success Response: "true" (text/plain)

Error Response (HTTP 500):

MessageDescription
error passwordWrong password
this file not this machine firmwareFirmware model mismatch
Insufficient disk spaceNot enough disk space
md5 check errorMD5 verification failed
need zip or pkgUnsupported file format

8. Static Resources & File Downloads

PathDescription
/photos/LF.jpgUser enrollment photo (by internal numeric ID)
/photos/CF_.jpgUser enrollment photo (by alias ID)
/logphotos/logimage.jpgAttendance log snapshot photo
/download/reportSummary attendance report (.xls, valid for 20s after generation)
/download/rawrecordRaw attendance records (.xls, valid for 20s after generation)
Static files are served from /data/res/webserver first; if not found, fallback to /usr/webserver.

9. Appendix: backupnum Reference

The backupnum field is used in getuserinfo, setuserinfo, deleteuser, adduser, deleteuserfp, deleteuserpalm and related commands to identify which biometric slot to operate on. Push commands (setuserinfo) additionally carry the template payload in record.

backupnumTypeDescriptionrecord encoding (push / export)Length after decoding
0-9FingerprintFingerprint at index 0-9 (up to 10 per user)Hex + zero run-length compression (N), not Base64810 bytes
10PasswordUser passwordNumber—
11CardRFID cardNumber—
12Full deleteDelete entire user record——
13Full deleteSame as 12——
40Left palmLeft hand palm vein templateBase641548 bytes
41Right palmRight hand palm vein templateBase641548 bytes
50Face photoFace JPEG imageBase64 (JPEG)≤ 512KB
51Face featureFace feature vector + 10 face key pointsBase64 (2-byte header + 1072-byte feature)1074 bytes

record quick reference:

Generating minimal testable payloads:

BASH# Fingerprint (810 zero bytes) -> use the literal string (810)
# Palm vein (1548 zero bytes) -> Base64 string of 2064 characters
python3 -c "import base64;print(base64.b64encode(bytes(1548)).decode())"
# Face feature (08 06 + 1072 zero bytes) -> Base64 starting with CAYA
python3 -c "import base64;print(base64.b64encode(b'\x08\x06'+bytes(1072)).decode())"
Fingerprint and palm vein templates are only available on models with the matching hardware (fingerprint module, or palm vein module); on unsupported models the corresponding backupnum is ignored.

10. Appendix: verifymode Reference

verifymode selects the verification method(s) a user may use (the device default uses the same values). Every method — including combinations such as "face + card" — has a fixed value; use one of the values below.

verifymodeVerification methodNotes
0Any methodDefault; no restriction
1FingerprintRequires fingerprint model
2Password—
3Card—
4Fingerprint + cardRequires fingerprint model
5Fingerprint + passwordRequires fingerprint model
6Password + fingerprintRequires fingerprint model
7Card + fingerprintRequires fingerprint model
8FaceRequires camera model
9Face + passwordRequires camera model
10Face + cardRequires camera model
11Card + password—
12Face + fingerprintRequires camera and fingerprint model
13QR codeRequires QR code support
14Face + (card or password)Requires camera model
15ID card (SFZ)Requires ID card reader
16Palm veinRequires palm vein model
191:N automatic matchSet by the device itself; normally not sent by the platform
20Any biometric of the personAny biometric or combination of the person
21Palm vein + faceRequires palm vein model
22Fingerprint + palm veinRequires fingerprint and palm vein model
23Card + palm veinRequires palm vein model
24Palm vein + passwordRequires palm vein model
25Card + face + passwordRequires camera model

Notes:


Document generated: 2026-05-06

Last updated: 2026-09-22 — added fingerprint / palm vein / face feature (with key points) push examples, record encoding rules and duplicate-check failure codes; corrected the verifymode value reference (see Appendix 10)

Based on webserver.cpp source code analysis