Anviz Local Web API

Anviz Local Web API wraps the Anviz device SDK into a Docker-ready web service. Your HR, payroll, workforce management, ERP, or security platform can communicate with compatible Anviz attendance and access devices using familiar HTTPS requests and JSON responses.

For system integrators and software teams, this means less low-level SDK work, faster proof-of-concept testing, and a cleaner path from device connection to business application integration.

Docker-ready for cross-platform deployment

Deploy the service quickly across different server environments with Docker, making integration faster, more consistent, and easier to maintain.

Multi-device handling

Requests for the same device are queued, while different device IDs can be processed in parallel for smoother operations.

Real-time data with Device Client mode

Devices can actively connect to the server and upload attendance records in real time for timely data synchronization.

Developer-friendly testing

Use the built-in health check, test script, and demo page to speed up integration validation.

Ideal for

HRMS and payroll platforms: synchronize attendance data directly into employee time, overtime, and payroll workflows.

Workforce management systems: connect device records to shift, scheduling, and multi-site workforce operations.

Security and access platforms: combine personnel data, access settings, and remote door actions in one system.

System integrator projects: accelerate custom integration work for enterprise, education, construction, hospitality, and public-sector customers.

Please submit a request to download the Local Web API: Become a Anviz Integrator Partner

1 Like

Anviz Local Web API User Guide

This document is for deployment and integration users. It covers Docker installation and configuration, container deployment, HTTPS/JWT configuration, API usage, and troubleshooting. The current service version enables HTTPS and JWT authentication by default.

Project Overview

Anviz Local Web API is a Python wrapper around libtc-b_new_sdk.so that exposes HTTPS REST APIs. Clients send command and payload through the unified /api/commands/execute endpoint. The server calls the SDK to communicate with attendance devices and returns JSON.

Core Files

  • app.py: HTTP/HTTPS service, JWT authentication, and command dispatching.
  • sdk_wrapper.py: SDK shared library wrapper, structure parsing, and device command implementation.
  • run_service.sh: Startup script for local or container execution.
  • crosschex-webapi.env: Runtime configuration file.
  • test_api.sh: API test script with automatic login and JWT retrieval.

Default Behavior

  • Listens on 0.0.0.0:5011 by default.
  • Enables HTTPS by default. Self-signed certificates are stored in certs/.
  • Enables JWT by default. command APIs require a Bearer Token.
  • Requests for the same device_id are queued. Different device_id values can be processed in parallel.

Step 1 Docker Environment Setup

If Docker is already installed on the system, skip this chapter. The following steps use Ubuntu 22.04/24.04 as examples. In production, install Docker Engine and the Compose plugin from the official Docker APT repository. Official documentation:

Install Docker Engine

# 1) Install base dependencies
sudo apt update
sudo apt install -y ca-certificates curl

# 2) Remove old packages that may conflict. Ignore errors if Docker was never installed
sudo apt remove -y docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc

# 3) Add the official Docker GPG key
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# 4) Add the Docker APT repository
sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

# 5) Install Docker Engine and the Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 6) Start Docker and enable it at boot
sudo systemctl enable --now docker
sudo systemctl status docker

Verify Docker

sudo docker run hello-world

Allow the Current User to Run Docker

sudo usermod -aG docker $USER
newgrp docker

# Verify that docker commands work without sudo
docker ps

If

docker ps

still reports insufficient permissions, log out of the current shell or restart the system and try again.

Configuration File

crosschex-webapi.env is the service runtime configuration file. run_service.sh loads it automatically.

In production, you must change

JWT_SECRET

and

AUTH_PASSWORD

, and you should replace the HTTPS certificate with a production certificate.

Setting Default / Example Description
HOST 0.0.0.0 Web API listen address.
PORT 5011 Web API listen port.
SDK_LIBRARY /app/libtc-b_new_sdk.so CrossChex SDK shared library path. In containers, this path must match the image or volume mount.
HTTPS_ENABLED 1 Whether HTTPS is enabled. Keep it enabled in production.
SSL_CERT_FILE /app/certs/server.crt HTTPS certificate path.
SSL_KEY_FILE /app/certs/server.key HTTPS private key path.
AUTH_ENABLED 1 Whether JWT authentication is enabled. Keep it enabled in production.
JWT_SECRET openssl rand -hex 32 JWT signing secret. Use a strong random string.
JWT_EXPIRES_SECONDS 3600 Token lifetime in seconds.
AUTH_PASSWORD Custom strong password Authentication password. Change it in production.
WEBHOOK_ENABLED 0 Set to 1 to enable realtime attendance record forwarding.
WEBHOOK_URL Empty HTTP/HTTPS endpoint that receives command 100 JSON. Leave empty to disable forwarding.
WEBHOOK_TOKEN Empty Optional Bearer Token. Leave empty to omit the Authorization header.

Generate JWT Secret

openssl rand -hex 32

Generate a Self-Signed Certificate for Testing Only

mkdir -p certs
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout certs/server.key \
  -out certs/server.crt \
  -days 3650 \
  -subj "/CN=127.0.0.1"

For production deployment, use a certificate issued by a trusted CA. With a self-signed certificate, calls require

curl -k

or importing the certificate into the client trust store.

Docker Deployment

Recommended Directory Layout

/webapi/
├── sdk/
│   ├── certs/
│   │   ├── server.crt
│   │   └── server.key
│   ├── demo/
│   │   └── index.html
│   ├── app.py
│   ├── crosschex-webapi.env
│   ├── libtc-b_new_sdk.so
│   ├── run_http.sh
│   ├── run_service.sh
│   ├── sdk_wrapper.py
│   └── test_api.sh
├── crosschex-webapi-usage.html
└── crosschex-webapi.tar

Load Image Files

docker load -i /webapi/crosschex-webapi.tar

Start with docker run

# Ubuntu
docker run -it --name crosschex-webapi --network host -v /webapi/sdk:/app crosschex-webapi:latest

# Mac/Windows
docker run -it --name crosschex-webapi -p 5010:5010 -p 5011:5011 -p 8080:8080 -p 5060:5060/udp -v d:/webapi/sdk:/app crosschex-webapi:latest

Check Container Runtime

docker ps --filter name=crosschex-webapi
docker logs -f crosschex-webapi
curl -k https://127.0.0.1:5011/healthz

JWT Authentication

Get Token

curl -k -X POST https://127.0.0.1:5011/api/auth/token \
  -H 'Content-Type: application/json' \
  -d '{"password":"change-this-password"}'

Successful response:

{
  "code": 200,
  "token_type": "Bearer",
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 3600
}

Call the command API

TOKEN=$(curl -k -sS -X POST https://127.0.0.1:5011/api/auth/token \
  -H 'Content-Type: application/json' \
  -d '{"password":"change-this-password"}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')

curl -k -X POST https://127.0.0.1:5011/api/commands/execute \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"command":23,"payload":{}}'

Authentication Errors

HTTP Status Scenario Response Example
401 Missing token, invalid token format, invalid signature, or expired token. {"code":401,"message":"Token expired."}

API Usage Specification

Health Check

The health check does not require JWT.

GET /healthz
curl -k https://127.0.0.1:5011/healthUnified Command Endpoint
POST /api/commands/execute
Content-Type: application/json
Authorization: Bearer <token>

{
  "command": 23,
  "payload": {}
}

All business commands use command to identify the operation and payload to carry command parameters.

Common Response Structure

{
  "code": 200,
  "command": 23,
  "data": { ... },
  "records": [ ... ],
  "count": 1
}

Not every API returns records and count. When there are no records, some APIs only return data.totalcnt=0.

Common Business Error Codes

code HTTP Status Description
400 Bad Request Invalid request JSON, missing parameters, or invalid parameter range.
401 Unauthorized Authentication failed.
404 Not Found Device not connected, API not found, or no event was received while waiting.
502 Bad Gateway SDK call failed immediately.
504 Gateway Timeout Timed out waiting for the device response.

Using the Web API Demo

Start the demo HTTP server

docker exec -it crosschex-webapi /app/run_http.sh

Open the Web API Demo page

When opening the demo page for the first time, click

Open healthz

first to remove browser network blocking. Then enter the correct API Base URL and password. The default password is CrossChex, but use the actual configured

AUTH_PASSWORD

.strong text

Troubleshooting

Symptom Cause Resolution
AUTH_ENABLED=1 but JWT_SECRET is empty crosschex-webapi.env was not loaded or JWT_SECRET is not configured. Confirm that run_service.sh loads the env file, or set ENV_FILE. Configure a strong random JWT_SECRET.
Missing Authorization Bearer token The command API was called without JWT. Call /api/auth/token first, then include Authorization: Bearer <token>.
Token expired JWT exceeded JWT_EXPIRES_SECONDS. Log in again to get a new token.
SSL cert file not found Certificate path is wrong or certs is not mounted in the container. Check SSL_CERT_FILE, SSL_KEY_FILE, and volume mounts.
Timed out while waiting for device response Device does not respond, network is unreachable, port is unreachable, or the event does not match. Check device IP, port 5010, container host network, device connection state, and SDK logs.
UDP search cannot find devices Container network isolation restricts UDP broadcast. Use --network host or network_mode: host.
HTTPS curl certificate error A self-signed certificate is used. Use -k during testing. Use a trusted certificate in production.

View Logs

# Docker run
docker logs -f crosschex-webapi

# With systemd deployment
journalctl -u crosschex-webapi -f
```**strong text**

API Command List V1.0

command Name Main payload parameters Description
1 Connect Device device_id, device_ip, device_port Call the SDK to connect to a device and return device ID, type, version, IP, and dev_idx.
2 Read New Records device_id Read record status first. If NewRecNum=0, return totalcnt=0 immediately.
3 Disconnect Device device_id Disconnect a connected device.
4 Read All Records device_id Read record status first. If TotalRecNum=0, return totalcnt=0 immediately.
5 Read Record Status device_id Return employee, fingerprint, password, card, total record, and new record counts.
6 Clear Records device_id Delete or clear device records.
7 Read Person Info device_id Read record status first. If EmployeeNum=0, return totalcnt=0 immediately.
8 Add/Modify Person device_id, userid, password, card_id, username, etc. Write basic person information.
9 Delete Person device_id, userid, operation Delete a person or person-related data.
10 Read Device Time device_id Return the current device time.
11 Set Device Time device_id, year, month, day, hour, minute, second Set the device time.
12 Initialize User Area device_id Clear user-related areas.
13 Initialize System device_id Initialize the device system. This is a high-risk operation.
14 Force Unlock device_id Trigger device force unlock.
15 Read SN device_id Read the device serial number.
16 Download Fingerprint Template device_id, userid, templateid Read a user fingerprint template.
17 Upload Fingerprint Template device_id, userid, templateid, template, template_len Write a user fingerprint template.
18 Download Face Image Template device_id, userid Read a face image template.
19 Upload Face Image Template device_id, userid, template Write a face image template.
20 Enroll Fingerprint Online device_id, userid, templateid Trigger online fingerprint enrollment on the device.
21 Enroll Face Online device_id, userid Trigger online face image enrollment on the device.
22 Read Records by User and Time device_id, userid, start_date, end_date Read the matching record count first and return immediately if it is 0.
23 List Connected Devices None Return the list of connected devices in the current service. records is always an array.
24 Read Period Settings device_id, timeid timeid range is 1..32. Returns start1/end1 through start7/end7.
25 Set Period Settings device_id, timeid, start1..end7 Time format is HH:mm.
26 Read Group Settings device_id, teamid teamid must be in the range 2..16. Returns timeid1..timeid4.
27 Set Group Settings device_id, teamid, timeid1..timeid4 teamid must be in the range 2..16.
28 Read Attendance Status device_id Return fp_len and status1..status8.
29 Set Attendance Status device_id, status1..status8 The status field length depends on the device type.
30 Search Devices None Search LAN devices over UDP and return IP, MAC, port, version, and related information.

Request and Response JSON Examples

The following examples show successful responses. Actual values may vary by device model, firmware version, and data content. Field structure follows the current API implementation.

command=1 Connect Device

Request JSON

{
  "command": 1,
  "payload": {
    "device_id": 1,
    "device_ip": "192.168.0.144",
    "device_port": 5010
  }
}

Response JSON

{
  "code": 200,
  "command": 1,
  "data": {
    "device_id": 1,
    "device_type": "FDEEP3M",
    "device_typeflag": 45154820,
    "device_ip": "192.168.0.144:5010",
    "device_version": "03.74.D6",
    "device_idx": 1
  }
}

command=2 Read New Records

Request JSON

{
  "command": 2,
  "payload": {
    "device_id": 1
  }
}

Response JSON

{
  "code": 200,
  "command": 2,
  "data": {
    "device_id": 1,
    "totalcnt": 1
  },
  "records": [
    {
      "userid": 1,
      "checktime": "2026-07-27 09:30:00",
      "backid": 16,
      "rectype": 128, //highest bit 1 means door opened, for example 128: opened+IN, 129: opened+OUT, 0: IN, 1: OUT
      "curidx": 1
    }
  ],
  "count": 1
}