ZiggyMeter REST API
ZiggyMeter Public API.
Authentication
ZiggyMeter API uses HTTP Bearer authentication. Obtain a short‑lived access token via the login endpoint, then send it in the Authorization header on subsequent requests.
Notes
- Tokens expire after
expires_in_secs. Re‑authenticate when expired. - Missing or invalid tokens will result in
401 Unauthorized. - Always include the exact header name
Authorizationwith valueBearer <token>.
Exceptions
POST /api/v1/system/logindoes not require a token.POST /api/v1/system/passworddoes not require a token (it validatesold_passwordinstead).
System API (/api/v1/system)
POST /api/v1/system/login
Login. Returns authorization token.
{
"username": "username",
"password": "password"
}| Field | Type | Description |
|---|---|---|
username | string | Username |
password | string | Password |
Response
{
"token": "vKEsedeLOBqLoSYYiWVrOF9To8T2RNK0ZV91aUwW",
"expires_in_secs": 3600
}| Field | Type | Description |
|---|---|---|
token | string | Authorization token |
expires_in_secs | integer | Remaining validity in seconds |
POST /api/v1/system/logout
Logout
Responses
200 OKwith empty body
GET /api/v1/system/version
Get firmware version.
Response
{
"firmware": {
"version": "1.0.320",
"date": "Jan 3 2026",
"time": "11:50:00"
},
"frontend": {
"version": "1.0.320",
"date": "Jan 3 2026",
"time": "11:36:31"
},
"build_number": 320,
"upgrade_url": "https://fw.ziggymeter.com/"
}| Field | Type | Description |
|---|---|---|
firmware | object | Firmware version details |
firmware.version | string | Firmware version |
firmware.date | string | Firmware build date |
firmware.time | string | Firmware build time |
frontend | object | Frontend version details |
frontend.version | string | Frontend version |
frontend.date | string | Frontend build date |
frontend.time | string | Frontend build time |
build_number | integer | Build number |
upgrade_url | string | URL for firmware upgrades |
GET /api/v1/system/status
Get device status.
Responses
{
"battery_voltage": 0,
"usb_voltage": 5.146,
"battery_powered": false,
"battery_status": 0,
"device_temperature": 26.6,
"zigbee_enabled": false,
"wifi_enabled": true,
"home_assistant_enabled": false
}| Field | Type | Description |
|---|---|---|
battery_voltage | number | Battery voltage |
usb_voltage | number | USB voltage |
battery_powered | boolean | Whether device is powered by battery |
battery_status | integer | Battery level in percent |
device_temperature | number | Device temperature (°C) |
zigbee_enabled | boolean | Zigbee integration enabled |
wifi_enabled | boolean | WiFi enabled |
home_assistant_enabled | boolean | Home Assistant integration enabled |
POST /api/v1/system/reboot
Reboot the device.
Responses
200 OKwith empty body. The device will restart immediately, causing current connections to be dropped.
POST /api/v1/system/factory_reset
Factory Reset. This will clear all configuration, including WiFi and admin password, and reboot the device.
Responses
200 OKwith empty body. The device will restart and return to its initial setup state.
POST /api/v1/system/password
Change the admin password.
This endpoint does not require a Bearer token. It validates old_password.
Request Body
{
"old_password": "old",
"new_password": "new"
}| Field | Type | Description |
|---|---|---|
old_password | string | Current admin password |
new_password | string | New admin password |
Responses
200 OKwith empty body400 Bad Requestif JSON fields are missing403 Forbiddenifold_passwordis invalid
POST /api/v1/system/ota
Sends firmware upgrade image. After successful transmission, the device will restart and update. The device is upgraded only when the entire image is transmitted. Failed transmission is ignored and does not render the device unresponsive.
TIP
Limit transmission rate in case of transmission problems. See API.
Request Body
Binary firmware image data (no JSON, raw binary).
Responses
200 OKwith empty body on successful transmission and update start.401 Unauthorizedif token is missing or invalid.500 Internal Server Errorif update fails.
Network API (/api/v1/network)
GET /api/v1/network/status
Get Network Status.
Responses
{
"ip": "192.168.20.242",
"netmask": "255.255.255.0",
"gateway": "192.168.20.1",
"hostname": "ZiggyMeter-1234",
"dhcp": true,
"ssid": "wifinetname",
"rssi": -89,
"channel": 4,
"authmode": 3,
"ap_mode": false
}| Field | Type | Description |
|---|---|---|
ip | string | IP address |
netmask | string | Network mask |
gateway | string | Gateway IP address |
hostname | string | Device hostname |
dhcp | boolean | DHCP enabled |
ssid | string | WiFi SSID |
rssi | integer | Signal strength |
channel | integer | WiFi channel |
authmode | integer | Authentication mode |
ap_mode | boolean | Access Point mode |
GET /api/v1/network/scan
Get WiFi networks.
Response
{
"hostname": "ZiggyMeter-1234",
"networks": [
{
"ssid": "Star-XYZ123",
"bssid": "A1B2C3D4E5F6",
"rssi": -87,
"channel": 4,
"authmode": 7
},
{
"ssid": "HomeNet-5G",
"bssid": "F0E1D2C3B4A5",
"rssi": -88,
"channel": 4,
"authmode": 3
},
{
"ssid": "GuestWiFi",
"bssid": "9A8B7C6D5E4F",
"rssi": -93,
"channel": 6,
"authmode": 3
},
{
"ssid": "OfficeSecure",
"bssid": "1F2E3D4C5B6A",
"rssi": -94,
"channel": 13,
"authmode": 3
}
]
}| Field | Type | Description |
|---|---|---|
hostname | string | Device hostname |
networks | array | List of available WiFi networks |
networks[].ssid | string | Network SSID |
networks[].bssid | string | Network BSSID (MAC address) |
networks[].rssi | integer | Signal strength (RSSI) |
networks[].channel | integer | WiFi channel |
networks[].authmode | integer | Authentication mode |
POST /api/v1/network/wifi
Post WiFi configuration.
Request Body
| Field | Type | Description |
|---|---|---|
ssid | string | WiFi SSID (required, 1-31 characters) |
password | string | WiFi password (required, up to 63 characters) |
dhcp | boolean | Enable DHCP (required) |
hostname | string | Device hostname (optional, non-empty string up to 31 characters) |
ip | string | Static IP address (required if DHCP false, valid IP) |
netmask | string | Network mask (required if DHCP false, valid IP) |
gateway | string | Gateway IP address (required if DHCP false, valid IP) |
apply | boolean | Apply settings immediately (optional, defaults to false) |
Responses
{
"ssid": "iot-net",
"dhcp": true,
"hostname": "ziggymeter1",
"ip": "192.168.8.177",
"netmask": "255.255.255.0",
"gateway": "192.168.8.1"
}| Field | Type | Description |
|---|---|---|
ssid | string | Configured WiFi SSID |
dhcp | boolean | DHCP status |
hostname | string | Configured hostname |
ip | string | Current/Static IP address |
netmask | string | Current/Static Network mask |
gateway | string | Current/Static Gateway IP |
WARNING
If apply is set to true, the device will attempt to connect to the new network immediately. This will cause the current connection to be dropped.
POST /api/v1/network/ap
Post Access Point configuration.
Request Body
| Field | Type | Description |
|---|---|---|
ap_ssid | string | Access Point SSID (optional, 1-31 characters) |
ap_password | string | Access Point password (optional, 8-63 characters) |
ap_enabled | boolean | Enable Access Point mode (optional) |
apply | boolean | Apply settings immediately (optional, defaults to false) |
Responses
{
"ap_ssid": "ZiggyMeter-1234",
"ap_enabled": true
}| Field | Type | Description |
|---|---|---|
ap_ssid | string | Configured AP SSID |
ap_enabled | boolean | AP mode status |
Zigbee API (/api/v1/zigbee)
GET /api/v1/zigbee/config
Get Zigbee configuration.
Response
{
"enabled": false,
"channel": 11,
"short_address": 0,
"extended_pan_id": "00124b0000000000",
"pan_id": 0
}| Field | Type | Description |
|---|---|---|
enabled | boolean | Zigbee enabled/disabled from stored config |
channel | integer | Current Zigbee channel |
short_address | integer | Current Zigbee short address |
extended_pan_id | string | Current Zigbee extended PAN ID (16 hex chars) |
pan_id | integer | Current Zigbee PAN ID |
POST /api/v1/zigbee/config
Set Zigbee configuration.
Request Body
{
"enabled": true
}| Field | Type | Description |
|---|---|---|
enabled | boolean | Enable or disable Zigbee support |
Responses
200 OKwith empty body
POST /api/v1/zigbee/reset
Trigger Zigbee reset. After reset, the device's internal Zigbee module is cleared and ready to join a new Zigbee network.
Responses
200 OKwith empty body. Current Zigbee pairing will be lost.
POST /api/v1/zigbee/map
Post Zigbee configuration to assign specific Zigbee data points to meter OBIS codes.
Request Body
{
"mapping": [
{
"obis": "1-0:15.8.0",
"mode": 0,
"mapping_id": "07020000"
},
{
"obis": "15.8.2",
"mode": 1,
"mapping_id": "07020001"
}
]
}| Field | Type | Description |
|---|---|---|
mapping | array | List of OBIS-to-Zigbee mapping entries |
mapping[].obis | string | OBIS code to map (e.g. 1.8.0 or 1-0:15.8.0) |
mapping[].mode | integer | Matching mode: 0 (match full OBIS code), 1 (match short OBIS code) |
mapping[].mapping_id | string | Zigbee mapping ID (8 hex characters, e.g. 07020000; cluster + ID) |
Responses
200 OKwith empty body401 Unauthorizedif token is missing or invalid400 Bad Requestif JSON structure is invalid
Home Assistant API (/api/v1/hass)
GET /api/v1/hass
Get Home Assistant configuration
Response
{
"enabled": false,
"url": "https://home-assistant.local:8123",
"cert_max_size": 10239
}| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether Home Assistant integration is enabled |
url | string | Home Assistant URL (present only when enabled) |
cert_max_size | integer | Maximum Home Assistant certificate size in bytes |
POST /api/v1/hass
Set Home Assistant configuration.
Request Body
| Field | Type | Description |
|---|---|---|
enabled | boolean | Enable or disable Home Assistant integration |
url | string | Home Assistant server URL (required if enabled) |
token | string | Home Assistant long-lived access token (required if enabled) |
lang | string | Language for OBIS descriptions (optional, defaults to 'en' if enabled) |
cert | string | PEM certificate for HTTPS connection (optional, clears if not provided when enabled) |
Responses
{
"enabled": true,
"url": "https://home-assistant.local:8123",
"cert_max_size": 10239
}| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether integration is enabled |
url | string | Target Home Assistant URL |
cert_max_size | integer | Maximum supported certificate size |
GET /api/v1/hass/send
Send a test publish to Home Assistant.
Response
{
"retcode": 0,
"http_status_code": 200
}| Field | Type | Description |
|---|---|---|
retcode | integer | return code (0 means success) |
http_status_code | integer | HTTP status code returned by Home Assistant |
Errors
400 Bad Requestif Home Assistant is not enabled
Meter API (IEC 62056-21) (/api/v1/iec62056)
GET /api/v1/iec62056/read
Trigger a meter readout and return the readings.
Responses
200
Returns the JSON structure with meter details and an array of OBIS readings.
{
"protocol": "IEC62056-21",
"meter_id": "/XXX6\\2YYYYYY",
"mode": "C",
"baudrate": 9600,
"timestamp": 293209783,
"status": 1,
"readings": [
{
"obis_long": "0-0:C.1.0",
"obis": "C.1.0",
"value1": "12345678",
"value2": "",
"value1_number": null,
"value1_unit": "",
"medium": 0,
"channel": 0,
"billing_period": null,
"mapping_id": "00000000",
"en": "Meter serial number"
},
{
"obis_long": "1-0:15.8.0",
"obis": "15.8.0",
"value1": "00000001000.657*kWh",
"value2": "",
"value1_number": 1000.657,
"value1_unit": "kWh",
"medium": 1,
"channel": 0,
"billing_period": null,
"mapping_id": "07020000",
"en": "Absolute active energy total"
}
]
}| Field | Type | Description |
|---|---|---|
protocol | string | Protocol used (IEC62056-21) |
meter_id | string | Meter identifier from the meter's identification telegram |
mode | string | Communication mode (e.g., 'C' or 'D') |
baudrate | integer | Baudrate used for communication |
timestamp | integer | Epoch timestamp of the reading |
status | integer | Readout status code (0 = success, other values indicate errors) |
readings | array | Array of OBIS readings |
readings[].obis_long | string | Full OBIS code (e.g. 1-0:1.8.0) |
readings[].obis | string | Short OBIS code (e.g. 1.8.0) |
readings[].value1 | string | Primary value as received from the meter |
readings[].value2 | string | Secondary value (e.g. timestamp of maximum), if present |
readings[].value1_number | number|null | Parsed numeric value of value1 |
readings[].value1_unit | string | Unit for value1 (e.g. 'kWh', 'kW', 'V') |
readings[].medium | integer|null | Medium identifier |
readings[].channel | integer|null | Channel identifier |
readings[].billing_period | integer|null | Billing period identifier |
readings[].mapping_id | string | Zigbee mapping ID (8 hex chars, e.g. 07020000), or 00000000 if not mapped |
readings[].en | string|null | English description of the OBIS code |
500
Meter timeout: The readout did not finish within the expected timeframe (~45s).Meter error: The meter returned an error response.
GET /api/v1/iec62056/last
Get the last available meter readings (does not trigger a new readout).
Responses
200
Same response schema as GET /api/v1/iec62056/read.
GET /api/v1/iec62056/config
Get meter configuration.
Responses
{
"mode_d_enabled": false,
"mode_d_baudrate": 2400,
"baudrate_max": 9600,
"schedule_min": 1,
"battery": false
}| Field | Type | Description |
|---|---|---|
mode_d_enabled | boolean | Whether IEC 62056 mode D is enabled |
mode_d_baudrate | integer | Baudrate for mode D communication |
baudrate_max | integer | Maximum supported baudrate |
schedule_min | integer | Minimum reading schedule interval (minutes) |
battery | boolean | Whether meter is battery powered |
POST /api/v1/iec62056/config
Post Meter Configuration.
Request Body
| Field | Type | Description |
|---|---|---|
mode_d_enabled | boolean | Enable or disable IEC 62056 mode D |
mode_d_baudrate | integer | Baudrate for mode D communication (must be valid baudrate) |
baudrate_max | integer | Maximum supported baudrate (must be valid baudrate) |
battery | boolean | Whether meter is battery powered |
schedule_min | integer | Minimum reading schedule interval in minutes (minimum -1) |
Responses
{
"mode_d_enabled": false,
"mode_d_baudrate": 2400,
"baudrate_max": 9600,
"schedule_min": 5,
"battery": false
}| Field | Type | Description |
|---|---|---|
mode_d_enabled | boolean | IEC 62056 mode D status |
mode_d_baudrate | integer | Configured mode D baudrate |
baudrate_max | integer | Maximum communication baudrate |
schedule_min | integer | Reading schedule interval (minutes) |
battery | boolean | Battery operation flag |