Skip to main content

Hikvision (ISAPI)

GEM controls Hikvision IP cameras and NVRs through the public ISAPI (Integrator Standard API) over HTTP/HTTPS with digest authentication. ISAPI is supported on essentially all modern Hikvision-branded firmware as well as several OEMs (LTS, Hilook, etc.).

For each camera or NVR you add one device; for each video channel you add one zone. A standalone IP camera is a single zone with address = 1.

Prerequisites​

  • A Hikvision device user account with at least Operator privilege.
  • For PTZ commands, the user account must additionally have PTZ permission on the channel — Operator alone is not sufficient.
  • ISAPI must be enabled on the device. It is enabled by default on all current firmware; some locked-down installs disable it.

Setup​

  1. Add a new device of type Hikvision (ISAPI) under System → Devices.
  2. Set:
    • Device IP — LAN IP of the camera or NVR.
    • Username / Password — local device credentials. The password is stored as a secure attribute.
    • Leave Port / Scheme at defaults (80 / http) for most installs. Switch to https (port 443) if the device only exposes HTTPS.
  3. Save and reload. The driver will hit /ISAPI/System/deviceInfo on connect; success is logged and the device is marked online.
  4. Add zones:
    • For an NVR, run get_channels first to enumerate input channels, then add a zone per channel with address = 1, 2, 3, …
    • For a single IP camera, one zone with address = 1 is enough.
  5. Optionally set the zone-level stream attribute to sub to use the lower-resolution stream for snapshots; default is main.

Attribute reference​

Device attributes​

AttributeRequiredTypeDefaultNotes
ipyesstring—LAN IP of the camera or NVR
usernameyesstring—Local device account
passwordyesstring (secure)—Local device password
portnoint80TCP port for ISAPI (443 for HTTPS)
schemenoenumhttphttp or https
auth_modenoenumdigestUse basic only for very old firmware
status_intervalnoint60000Liveness poll period (ms)

Zone attributes​

AttributeRequiredTypeNotes
addressyesstringChannel number, e.g. 1, 2, 3
streamnoenum (main/sub)Picks ISAPI ddss stream id; defaults to main
stream_urlnostringOptional RTSP/HTTP URL for live preview widgets

Channel id format​

ISAPI uses a 3-digit ddss channel id in URLs, derived from the channel number:

Human channelStreamISAPI channel id
1main101
1sub102
2main201
8main801

The driver converts your zone address (the human channel number) to the ddss form automatically. You only ever supply the human number.

Commands​

CommandArgsNotes
snapshotaddressReturns {content_type: 'image/jpeg', base64: '…'}. Honors zone stream attribute.
ptz_pan_tiltaddress, pan, tiltContinuous PTZ; pan/tilt are -100..100.
ptz_zoomaddress, zoomContinuous zoom; -100..100.
ptz_stopaddressSends {pan:0, tilt:0, zoom:0} continuous PTZ to halt motion.
ptz_presetaddress, presetRecall preset id 1-255.
get_channels—NVR: lists /ISAPI/ContentMgmt/InputProxy/channels. IP camera: falls back to /ISAPI/Streaming/channels.
get_device_info—Raw response of /ISAPI/System/deviceInfo (model, firmware, serial).

Auth model​

The driver uses HTTP digest authentication by default — opts.auth = {username, password, sendImmediately:false} against the shared generic_http base. The base library handles the 401 → digest handshake transparently.

If a device runs older firmware that only supports basic auth (you'll see WWW-Authenticate: Basic in the 401), set auth_mode to basic.

Connection and liveness​

  • On connect the driver reads /ISAPI/System/deviceInfo. If the camera does not answer (powered off, unreachable, returning a server error), it tries again after 30 seconds, doubling the wait up to 5 minutes, so a camera that comes up after GEM does not need a manual reload.
  • If the camera refuses the credentials (HTTP 401) at connect, the driver does not retry: Hikvision locks the account after a few wrong attempts. Fix the username/password and reload the device.
  • Once connected, deviceInfo is polled every status_interval ms (default 60000). After three failed polls in a row the wait doubles each time, up to 5 minutes (or the configured interval, if that is longer); the first successful poll returns to the normal interval. A blank, zero, negative or unreadable status_interval means the 60 s default, and values under 1000 are treated as 1000.
  • A 401 marks the device offline; a 403 does not, because it usually means the account lacks PTZ permission on one channel rather than the device being down.
  • With scheme set to https and no port attribute, the driver uses port 443. An unreadable or out-of-range port falls back to the scheme's default with a warning in the log.

Replies treated as errors​

  • A PTZ write answered with an ISAPI ResponseStatus whose statusCode is not 1 (OK) or 7 (reboot required) returns an error naming the status, for example isapi status 4 (notSupport).
  • An HTML page answered with a 2xx status (a login page or another web server at that address) returns unexpected html reply.
  • A snapshot reply that is empty, or is an XML/HTML/JSON page instead of an image, returns an error instead of being passed on as a JPEG.
  • Zone addresses are matched after trimming spaces; an address that does not match one of the device's zones is refused before anything is sent.

Known limitations​

  • No event subscription yet. /ISAPI/Event/notification/alertStream (long-lived chunked event push) is not wired in this driver. Liveness polling on deviceInfo is the only background traffic.
  • No motion / tampering / line-cross hooks. When events land, integrators will surface those as zone attributes.
  • PTZ continuous self-stops on most firmware after a few seconds. Always issue ptz_stop for predictable behavior.
  • No relative PTZ. Only continuous and preset PTZ paths are exposed; relative PTZ (/ISAPI/PTZCtrl/channels/{id}/relative) is a future addition.

Troubleshooting​

SymptomLikely cause
All requests return 401Wrong credentials, account locked after repeated failures, or user lacks the Operator role. Hikvision locks accounts after ~5 wrong attempts.
snapshot returns 404Zone address does not match an enabled input channel. Run get_channels to confirm.
PTZ commands return 403Operator privilege is not enough — the user account needs explicit PTZ permission on that channel.
Works on http but not httpsSelf-signed certs are tolerated by default. If https still fails, the device may only listen on the alternate port (commonly 443 vs 8443).
Sporadic timeouts on NVRsNVRs can be slow under load; raise status_interval to reduce poll pressure.

Wire format reference​

GET /ISAPI/System/deviceInfo Authorization: Digest …
GET /ISAPI/ContentMgmt/InputProxy/channels (NVR)
GET /ISAPI/Streaming/channels (single camera fallback)
GET /ISAPI/Streaming/channels/101/picture → JPEG bytes
PUT /ISAPI/PTZCtrl/channels/101/continuous
<PTZData><pan>40</pan><tilt>0</tilt><zoom>0</zoom></PTZData>
PUT /ISAPI/PTZCtrl/channels/101/presets/3/goto