All chapters

Provisioning API

The provisioning API at /api/v1 sets Huntress up from code: create a place with its sensors, enrol people, register alarm panels, and read back the tokens each device needs. It is built to be run again and again; nothing it does is destructive.

API keys#

  1. An Owner or Admin opens My account → API keys and creates a key: a name, a scope and an optional expiry.
  2. Copy the key at once. It is shown once; Huntress stores only its SHA-256 hash.
  3. Send it in every request: Authorization: Bearer hnt_….
  • A key looks like hnt_<8-character id>_<43-character secret>. Only the id is ever shown or logged afterwards.
  • Scopes: sites:read lists and reads; sites:write also creates (it implies read). The same two scopes cover places, people and panels.
  • A key works only while the member who created it is still an Owner or Admin. If they are demoted or removed, their keys are suspended or revoked at once.
  • An organisation can have 20 active keys. You can revoke a key at any time; the list shows each key's status, last use and the address it was last used from.
  • HTTPS is required (ApiKeys:RequireHttps, default on outside development). Behind a proxy, ForwardedHeaders must restore the original scheme.
  • Limits: 120 requests per minute per key, and 20 failed authentications per 5 minutes per client address, after which that client is refused for the rest of the window.
  • Keys never authenticate through cookies, and a signed-in browser session never authenticates the API.
Secrets in, secrets outResponses contain the ingest tokens of your devices, so they are sent with Cache-Control: no-store. Keep API keys out of source control; a key scanner can match hnt_[a-z2-9]{8}_[A-Za-z0-9]{43}.

Endpoints#

Endpoints
RequestScopePurpose
GET /api/v1/sitessites:readList places with their sensor counts.
GET /api/v1/sites/{id}sites:readA place with its sensors and their tokens.
POST /api/v1/sites/ensuresites:writeCreate a place and its sensors if they do not exist.
GET /api/v1/peoplesites:readPeople with their Pulse tokens.
POST /api/v1/people/ensuresites:writeCreate people (each with their Pulse tracker).
GET /api/v1/panelssites:readAlarm panels with account codes and zones.
POST /api/v1/panels/ensuresites:writeCreate alarm panels and their zones.

How “ensure” behaves#

  • Idempotent. The call matches by name. What exists is left as it is, what is missing is created, and the answer lists everything with a created flag, so the same script can run on every deployment.
  • Additive. It never changes a setting, never deletes and never takes over a panel's encryption key. A place only gains missing sensors; a panel only gains missing zones.
  • All or nothing. If anything conflicts, for example a sensor with that name but another type, or an account code that belongs to another organisation, the answer is 409 with the reasons and nothing is written.
  • Validated. Bad input answers 400 with a list of the offending fields. A body over 256 KB answers 413.
  • Limits per request: 200 sensors, 200 people, 50 panels and 200 zones per panel (zone numbers up to 65535). Names are up to 100 characters, descriptions up to 500.

A place with sensors#

`type` is the numeric id of the sensor type; see the table below

curl -X POST https://<host>/api/v1/sites/ensure \
  -H "Authorization: Bearer hnt_…" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Warehouse North",
        "description": "Main warehouse",
        "sensors": [
          { "name": "Dock door",  "type": 14 },
          { "name": "Freezer 1",  "type": 72 },
          { "name": "Gate camera", "type": 104 }
        ]
      }'
{
  "id": 7, "name": "Warehouse North", "created": true,
  "sensors": [
    { "id": 31, "name": "Dock door", "type": 14, "typeName": "Door Magnetic Contact", "unit": "", "status": "Unknown",
      "lastSeen": "2026-10-12T09:00:00Z", "token": "6f1c2a3e-…", "created": true },
    …
  ]
}

People#

curl -X POST https://<host>/api/v1/people/ensure -H "Authorization: Bearer hnt_…" \
  -H "Content-Type: application/json" \
  -d '{ "people": [ { "name": "Anna Berg", "pulseEnabled": true } ] }'

Each person is created with a Pulse tracker, and the answer holds its token: the key to give the person's phone. Pulse is off unless the request sets pulseEnabled to true; while it is off the token refuses every event, and for someone who already exists it is switched on from their page, never through the API.

Alarm panels#

curl -X POST https://<host>/api/v1/panels/ensure -H "Authorization: Bearer hnt_…" \
  -H "Content-Type: application/json" \
  -d '{ "panels": [ { "name": "Main panel", "siteName": "Warehouse North",
        "zones": [ { "number": 1, "name": "Dock door" }, { "number": 2, "name": "Office PIR" } ] } ] }'

The panel is created in a place that already exists (named by siteName). If you give no accountCode Huntress generates a random 8-character one and returns it. An account code is unique across all organisations, so a code that is taken is a 409.

Sensor type ids#

type in an ensure request is the numeric id of a sensor type. Every selectable type is accepted, as are Temperature, Humidity and Air Quality (marked API only), which are hidden from the interface's pickers. The Pulse tracker is created through people, not here.

Show the id of every sensor type
Sensor type ids accepted by the provisioning API
IdTypeCategory
1 Humidity (API only) Environmental
3 Temperature (API only) Environmental
5 Air Quality (VOC) (API only) Environmental
6 Passive Infrared (PIR) Motion Intrusion Detection
7 Dual-Tech Motion (PIR + Microwave) Intrusion Detection
8 Microwave Motion Intrusion Detection
9 Ultrasonic Motion Intrusion Detection
10 Photoelectric Infrared Beam Intrusion Detection
11 Laser Beam Detector Intrusion Detection
12 Glass Break Acoustic Intrusion Detection
13 Shock / Vibration Intrusion Detection
14 Door Magnetic Contact Intrusion Detection
15 Window Magnetic Contact Intrusion Detection
16 Door Tilt Intrusion Detection
17 Pressure Mat Intrusion Detection
18 Capacitance Proximity Intrusion Detection
19 Fence Vibration Intrusion Detection
20 Fiber-Optic Fence Intrusion Intrusion Detection
21 Outdoor PIR Motion Perimeter Security
22 Outdoor Dual-Tech Motion Perimeter Security
23 Radar Motion Detection Perimeter Security
24 Thermal Intrusion Detection Perimeter Security
25 LiDAR Intrusion Detection Perimeter Security
26 Seismic Ground Intrusion Perimeter Security
27 Buried Cable Perimeter Perimeter Security
28 Microwave Barrier Perimeter Security
29 Active Infrared Barrier Perimeter Security
30 Vehicle Magnetic Loop Perimeter Security
31 Video Motion Detection Video / Optical
32 Line-Crossing Analytics Video / Optical
33 Intrusion Zone Analytics Video / Optical
34 Object Left-Behind Detection Video / Optical
35 Object Removal Detection Video / Optical
36 Facial Recognition Video / Optical
37 License Plate Recognition Video / Optical
38 Camera Defocus Detection Video / Optical
39 Camera Tamper Detection Video / Optical
40 Thermal Anomaly Camera Video / Optical
41 Crowd Density Monitoring Video / Optical
42 Gunshot Detection Acoustic / Audio
43 Aggression Detection Audio Acoustic / Audio
44 Explosion Acoustic Acoustic / Audio
45 Glass Vibration Detection Acoustic / Audio
46 Vehicle Crash Detection Acoustic / Audio
47 Machinery Abnormal Sound Acoustic / Audio
48 Drone Acoustic Detection Acoustic / Audio
49 RF Jammer Detection RF / Wireless
50 Unauthorized Wireless Device RF / Wireless
51 Bluetooth Beacon Proximity RF / Wireless
52 Ultra-Wideband Asset Tracking RF / Wireless
53 RFID Gate Detection RF / Wireless
54 Cellular Signal Monitoring RF / Wireless
55 Photoelectric Smoke Life Safety
56 Ionization Smoke Life Safety
57 Fixed Temperature Heat Life Safety
58 Rate-of-Rise Heat Life Safety
59 Carbon Monoxide Life Safety
60 Carbon Dioxide Life Safety
61 Methane / Natural Gas Life Safety
62 Propane / LPG Gas Life Safety
63 Hydrogen Gas Life Safety
64 Flame Detector (UV) Life Safety
65 Flame Detector (IR) Life Safety
66 Water Leak Detector Environmental
67 Flood Sensor Environmental
68 Particulate Matter (PM2.5/PM10) Environmental
69 Air Pressure Environmental
70 Airflow Environmental
71 Refrigerant Gas Leak Environmental
72 Freezer Temperature Environmental
73 Server Room Humidity Environmental
74 Structural Strain Gauge Structural / Infra.
75 Building Vibration Structural / Infra.
76 Foundation Movement Structural / Infra.
77 Crack Monitoring Structural / Infra.
78 Elevator Door Obstruction Structural / Infra.
79 Escalator Safety Structural / Infra.
80 Power Failure Structural / Infra.
81 UPS Battery Health Structural / Infra.
82 Generator Status Structural / Infra.
83 Radiation Detection Chemical / Hazard
84 Industrial Chemical Gas Chemical / Hazard
85 Oxygen Deficiency Chemical / Hazard
86 Ammonia Gas Chemical / Hazard
87 Hydrogen Sulfide Chemical / Hazard
88 Dust Concentration Chemical / Hazard
89 Server Rack Door Asset / Equipment
90 Equipment Tilt Asset / Equipment
91 Asset Removal Asset / Equipment
92 Safe Door Asset / Equipment
93 Cabinet Open Asset / Equipment
94 Weapon Locker Asset / Equipment
95 ATM Vibration Asset / Equipment
96 Cash Drawer Asset / Equipment
97 Door Position Access Control
98 Door Forced-Open Access Control
99 Door Held-Open Access Control
100 Request-to-Exit Motion Access Control
101 Vehicle Gate Position Access Control
102 Parking Occupancy Access Control
104 Live Camera Video / Optical
105 Switch / Relay Control / Outputs
106 Door Strike / Momentary Control / Outputs
107 Dimmer Control / Outputs
108 Light (colour) Control / Outputs
109 Door Lock Control / Outputs
110 Blind / Shutter Control / Outputs
111 Garage Door / Gate Control / Outputs
112 Shut-off Valve Control / Outputs
113 Thermostat Control / Outputs
114 Fan / Ventilation Control / Outputs
115 Siren / Strobe Control / Outputs
116 Number Output Control / Outputs
117 Select Output Control / Outputs
118 Button / Remote Control / Outputs
119 Panic Button Intrusion Detection
120 Illuminance Environmental
121 Power Meter Asset / Equipment

The Hunt API and the provisioning API#

They are separate on purpose. A device holds a token that lets it report as one sensor; a script holds an API key that lets it manage the setup. Neither can do the other's job. Interactive API documentation (Swagger) is served only in development builds; this page is the reference for production. Signed in, My account → Provisioning API has the same reference with your own server's address in every example, in curl, PowerShell and Python.

Connection lost
Attempting to reconnect…