Cozify Han API (1.0)

Download OpenAPI specification:

This is the OpenAPI specification for the Cozify HAN reader.

System

System status, events, and connectivity

AuthToken

Returns a short-lived Cozify HAN bearer JWT for the built-in reader interface.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_AUTH_TOKEN",
  • "tokenType": "Bearer",
  • "accessToken": "string",
  • "audience": "cozify-han",
  • "scope": "ota:write",
  • "expiresIn": 300
}

Info

Returns general information about the HAN reader.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_STATE_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "name": "Cozify-HAN-123-456",
  • "model": "HAN",
  • "serial": "HAN12345678",
  • "version": "1.0.1.0",
  • "state": "REGISTERED",
  • "mac": "AA:BB:CC:DD:EE:FF",
  • "ethIp": "192.168.1.50",
  • "wifiIp": "192.168.2.50",
  • "online": true,
  • "rebootPending": false,
  • "rebootReason": "OTA_UPDATE",
  • "channel": "release"
}

WebSocket

Establishes a WebSocket connection to the HAN reader.

This endpoint upgrades the HTTP connection to a WebSocket. The WebSocket protocol is used for real-time, bidirectional communication.

When the connection is established, the server sends an initial snapshot of the current HAN reader state so the client can initialize its view without making a separate request. After that, the connection remains open and the server streams ongoing updates as new HAN data and state changes become available.

Message payload discriminator values used:

  • HAN_METER_MESSAGE
  • HAN_STATE_MESSAGE
  • HAN_CONFIGURATION_MESSAGE
  • HAN_OTA_MESSAGE
Authorizations:
None

Responses

ServerSentEvents

Opens a stream of server-sent events (SSE) from the HAN reader. The response uses the text/event-stream content type.

When the connection is established, the server sends an initial snapshot of the current HAN reader state so the client can initialize its view without making a separate request. After that, the connection remains open and the server streams ongoing updates as new HAN data and state changes become available.

Payload discriminator values are used in event names to indicate the type:

  • HAN_METER_MESSAGE
  • HAN_STATE_MESSAGE
  • HAN_CONFIGURATION_MESSAGE
  • HAN_OTA_MESSAGE
Authorizations:
None

Responses

Health

Returns health and status information about the HAN reader.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_HEALTH_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "hostname": "Cozify-HAN-123-456",
  • "heap_size": 327680,
  • "free_heap_size": 182144,
  • "free_heap_percent": 55.6,
  • "minimum_free_heap_size": 176320,
  • "tlsReady": true,
  • "wifi_rssi": -58,
  • "cpu_reset_reason": "RST_POWERON",
  • "connections": {
    },
  • "uptime_ms": 1234567,
  • "services": [
    ]
}

Firmware

Returns firmware version metadata for the HAN reader.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_FIRMWARE_MESSAGE",
  • "version": "1.0.1.9",
  • "commit": "abcdef1",
  • "time": "2025-01-01T12:00:00Z",
  • "activeSlot": "slot1",
  • "assetsVersion": "0123456789ab"
}

LegacyFirmwareUpdateState

Returns the legacy local firmware upload state for backwards compatibility with released /update integrations.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "status": "INSTALL_IN_PROGRESS",
  • "updating": true,
  • "rebootPending": false,
  • "bytesWritten": 262144,
  • "bytesExpected": 1048576,
  • "progress": 25,
  • "error": "invalid_firmware"
}

LegacyFirmwareUpload

Uploads a firmware image using multipart form field filename and preserves the released /update behavior by activating the uploaded image and requesting reboot after validation succeeds. New staged OTA workflows are available under /ota.

Authorizations:
None
Request Body schema: multipart/form-data
required
filename
required
string <binary>

Firmware binary image.

Responses

Response samples

Content type
application/json
{
  • "status": "INSTALL_IN_PROGRESS",
  • "updating": true,
  • "rebootPending": false,
  • "bytesWritten": 262144,
  • "bytesExpected": 1048576,
  • "progress": 25,
  • "error": "invalid_firmware"
}

OtaState

Returns the current OTA lifecycle state. This is the REST snapshot equivalent of the HAN_OTA_MESSAGE realtime event.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_OTA_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "status": "INSTALL_IN_PROGRESS",
  • "version": "1.0.2.0",
  • "releaseNotes": "string",
  • "releaseNotesUrl": "http://example.com",
  • "source": "local",
  • "critical": false,
  • "forced": false,
  • "allowDownload": false,
  • "progress": 42,
  • "activeSlot": "slot1",
  • "stagedSlot": "slot2",
  • "stagedVersion": "1.0.2.0",
  • "error": "invalid_firmware"
}

UploadOtaImage

Uploads an OTA firmware image using multipart form field filename. The request must include a Cozify HAN bearer JWT with scope containing ota:write or ota:*. The reader validates the image and stages it in the inactive OTA slot. Use /ota/activate to activate the staged image and reboot.

Authorizations:
CozifyHanJwt
Request Body schema: multipart/form-data
required
filename
required
string <binary>

Firmware binary image.

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_OTA_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "status": "INSTALL_IN_PROGRESS",
  • "version": "1.0.2.0",
  • "releaseNotes": "string",
  • "releaseNotesUrl": "http://example.com",
  • "source": "local",
  • "critical": false,
  • "forced": false,
  • "allowDownload": false,
  • "progress": 42,
  • "activeSlot": "slot1",
  • "stagedSlot": "slot2",
  • "stagedVersion": "1.0.2.0",
  • "error": "invalid_firmware"
}

DownloadOtaImage

Requests downloading the available cloud OTA image. The configured firmware update policy controls what happens after the image is staged. With automatic, the reader activates the staged image and reboots automatically. With download or manual, the image waits in READY_TO_REBOOT until /ota/activate is called. Progress and resulting state are reported through the returned HAN_OTA_MESSAGE snapshot and subsequent SSE or WebSocket HAN_OTA_MESSAGE events.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_OTA_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "status": "INSTALL_IN_PROGRESS",
  • "version": "1.0.2.0",
  • "releaseNotes": "string",
  • "releaseNotesUrl": "http://example.com",
  • "source": "local",
  • "critical": false,
  • "forced": false,
  • "allowDownload": false,
  • "progress": 42,
  • "activeSlot": "slot1",
  • "stagedSlot": "slot2",
  • "stagedVersion": "1.0.2.0",
  • "error": "invalid_firmware"
}

ClearOtaState

Clears a failed OTA state after the user has acknowledged the error. Active OTA operations, staged updates, and reboot-pending states are not cleared.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_OTA_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "status": "INSTALL_IN_PROGRESS",
  • "version": "1.0.2.0",
  • "releaseNotes": "string",
  • "releaseNotesUrl": "http://example.com",
  • "source": "local",
  • "critical": false,
  • "forced": false,
  • "allowDownload": false,
  • "progress": 42,
  • "activeSlot": "slot1",
  • "stagedSlot": "slot2",
  • "stagedVersion": "1.0.2.0",
  • "error": "invalid_firmware"
}

ActivateOtaImage

Activates a staged OTA image and requests a reboot. This is useful for manual OTA flows after a validated image has reached READY_TO_REBOOT.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_OTA_MESSAGE",
  • "ts": 1735682400000,
  • "uuid": "7f2f8c1e-2c6d-4a25-b2b1-6f6a27d5f5de",
  • "status": "INSTALL_IN_PROGRESS",
  • "version": "1.0.2.0",
  • "releaseNotes": "string",
  • "releaseNotesUrl": "http://example.com",
  • "source": "local",
  • "critical": false,
  • "forced": false,
  • "allowDownload": false,
  • "progress": 42,
  • "activeSlot": "slot1",
  • "stagedSlot": "slot2",
  • "stagedVersion": "1.0.2.0",
  • "error": "invalid_firmware"
}

Configuration

HAN reader configuration and setup

Setup

Sets up the HAN reader with basic WiFi configuration. Accepts a JSON object with WiFi enablement, SSID, and password. Returns success status and message. Saved network settings are applied live without rebooting.

Authorizations:
None
Request Body schema: application/json
required
s
required
boolean

Enable WiFi (must be true)

ss
required
string

WiFi SSID

sp
required
string

WiFi password

Responses

Request samples

Content type
application/json
{
  • "s": true,
  • "ss": "string",
  • "sp": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "string"
}

Configuration

Returns the current HAN reader configuration.

  • Meter settings include the main fuse value, optional meter timestamp timezone, and meter timestamp correction used by the HAN reader.
  • If the meter timezone is an empty string, the HAN reader uses the device timezone.
  • Supported timezone values include built-in Linux timezone IDs from /definitions.
  • Network policy controls whether the reader uses Ethernet, WiFi STA, explicit Ethernet plus STA, or automatic Ethernet-first fallback.
  • Ethernet and WiFi settings include enablement, network mode (dhcp/static), and network details.
  • Passwords and secrets are masked as "***" if configured.
Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_CONFIGURATION",
  • "v": "string",
  • "t": "string",
  • "s": true,
  • "p": 0,
  • "pc": "EUR",
  • "pa": "FI",
  • "np": "auto",
  • "up": "automatic",
  • "bhf": true,
  • "m": {
    },
  • "e": {
    },
  • "w": {
    }
}

ConfigurationUpdate

Updates the HAN reader configuration. Accepts a JSON object with any subset of the configuration fields as defined in the GET response. Returns success status and message. Some changes may require a HAN reader reboot.

Authorizations:
None
Request Body schema: application/json
required
t
string

Device timezone. Built-in Linux timezone IDs from /definitions are accepted.

s
boolean

Use spot price

p
number >= 0

Fixed electricity price in minor currency units per kWh, such as cents/kWh or öre/kWh.

pc
string
Enum: "EUR" "SEK" "NOK" "DKK" "GBP" "PLN" "CZK" "HUF" "RON" "BGN" "CHF" "ISK"

Price currency.

pa
string
Enum: "FI" "EE" "SE1" "SE2" "SE3" "SE4"

Spot price bidding area.

np
string
Enum: "auto" "eth" "sta" "eth_sta"

Network policy. Automatic tries Ethernet first and falls back to STA if Ethernet is unavailable. Ethernet plus WiFi keeps both network chips active.

up
string
Enum: "automatic" "download" "manual"

Firmware update policy. Automatic downloads and installs online updates. Download downloads online updates and waits for manual installation. Manual waits for the user before downloading online updates.

bhf
boolean

Reboot the device after repeated failed attempts to open a cloud connection.

object

Meter settings used by the HAN reader

object

Ethernet settings

object

WiFi settings

Responses

Request samples

Content type
application/json
{
  • "t": "string",
  • "s": true,
  • "p": 0,
  • "pc": "EUR",
  • "pa": "FI",
  • "np": "auto",
  • "up": "automatic",
  • "bhf": true,
  • "m": {
    },
  • "e": {
    },
  • "w": {
    }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "string",
  • "rebootRequired": true
}

Definitions

Returns static values and selectable definitions for UI clients.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_DEFINITIONS",
  • "currencies": [
    ],
  • "priceAreas": [
    ],
  • "timezones": [
    ]
}

Reboot

Requests a HAN reader reboot. Connected SSE and WebSocket clients receive a HAN_STATE_MESSAGE with rebootPending set to true before the device restarts.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "reboot:ok",
  • "rebootRequired": true
}

Network

Network operations and WiFi management

ScanNetworks

Initiates or returns the result of a WiFi network scan. If a scan is running or requested, returns status. If scan is complete, returns a list of found networks with details.

Note: Performing a WiFi scan may temporarily disconnect the HAN reader from its currently connected WiFi network.

  • If the scan is running or just started, returns { "status": "SCAN_RUNNING" }.
  • If the scan failed, returns { "status": "SCAN_FAILED" }.
  • If the scan succeeded, returns { "status": "SCAN_SUCCESS", "networks": [...] }.

Each network entry includes SSID, BSSID, RSSI, channel, and authentication type.

Authorizations:
None
header Parameters
X-Scan-Start
string

If present, triggers a new WiFi scan.

Responses

Response samples

Content type
application/json
{
  • "status": "SCAN_RUNNING",
  • "networks": [
    ]
}

Meter

Electricity meter data reported by the HAN reader

Meter

Returns the latest electricity meter data received by the HAN reader. This endpoint is intended for the latest live reading values reported by the electricity meter.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_METER_MESSAGE",
  • "ts": 173568240000,
  • "ic": 1000,
  • "ec": 10,
  • "ric": 1,
  • "rec": 1,
  • "p": [
    ],
  • "pi": [
    ],
  • "pe": [
    ],
  • "r": [
    ],
  • "ri": [
    ],
  • "re": [
    ],
  • "u": [
    ],
  • "i": [
    ]
}

Meter identity

Returns low-churn electricity meter identity fields parsed from HAN telegrams. This endpoint is intended for metadata that changes rarely, so clients can fetch meter identity separately from high-frequency /meter polling.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_METER_IDENTITY_MESSAGE",
  • "manufacturerId": "KFM",
  • "deviceType": "E",
  • "meterId": "A123456789012345",
  • "meterName": "AM550"
}

Data

Returns a compact legacy snapshot of the latest electricity meter reading, configured main fuse, current price, and estimated cost values.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_COMPACT_DATA_MESSAGE",
  • "im": 18000,
  • "mf": 25,
  • "i": 1000,
  • "e": 0,
  • "ri": 10,
  • "re": 0,
  • "ic": 1000,
  • "ec": 10,
  • "ric": 1,
  • "rec": 1,
  • "u1": 230,
  • "u2": 230,
  • "u3": 230,
  • "i1": 6.1,
  • "i2": 5.8,
  • "i3": 6,
  • "p": 8.123456,
  • "pc": "EUR",
  • "c": 1735682400,
  • "ep": {
    }
}

Prices

Returns the current active electricity price, configured currency, and known price time slots.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_PRICES_MESSAGE",
  • "price": 8.123456,
  • "currency": "EUR",
  • "prices": [
    ]
}

Telegram

Returns the most recent successfully parsed HAN telegram as plain text. The response body contains the exact telegram text that produced the latest valid meter reading.

Authorizations:
None

Responses

Raw input buffer

Returns the rolling raw HAN input buffer as bytes in oldest-to-newest order. The payload contains up to 4096 of the latest bytes received by the HAN reader before decoding.

Authorizations:
None

Responses

History

Historical electricity meter data collected by the HAN reader

Hourly history

Returns recent high-resolution history samples. Arrays are column-oriented: values at the same index belong to the same sample. Samples are ordered oldest to newest. The newest sample can be a live rolling bucket for the current 10-second period and is marked incomplete until finalized.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_HOURLY_HISTORY_MESSAGE",
  • "x": 1735682400,
  • "t": [
    ],
  • "f": [
    ],
  • "i": [
    ],
  • "e": [
    ],
  • "c_min": [
    ],
  • "c_avg": [
    ],
  • "c_max": [
    ]
}

Weekly history

Returns recent 15-minute history samples. Arrays are column-oriented: values at the same index belong to the same sample. Samples are ordered oldest to newest. The newest sample can be a live rolling bucket for the current 15-minute period and is marked incomplete until finalized.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_WEEKLY_HISTORY_MESSAGE",
  • "x": 1735682400,
  • "t": [
    ],
  • "f": [
    ],
  • "i": [
    ],
  • "e": [
    ],
  • "c_min": [
    ],
  • "c_max": [
    ],
  • "c_avg": [
    ],
  • "p": [
    ],
  • "pc": "EUR"
}

Monthly history

Returns recent daily history samples. Arrays are column-oriented: values at the same index belong to the same sample. Samples are ordered oldest to newest. The newest sample can be a live rolling bucket for the current day and is marked incomplete until finalized.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_MONTHLY_HISTORY_MESSAGE",
  • "x": 1735682400,
  • "t": [
    ],
  • "f": [
    ],
  • "i": [
    ],
  • "e": [
    ],
  • "c_min": [
    ],
  • "c_max": [
    ],
  • "c_avg": [
    ]
}

Yearly history

Returns recent monthly history samples. Arrays are column-oriented: values at the same index belong to the same sample. Samples are ordered oldest to newest. The newest sample can be a live rolling bucket for the current month and is marked incomplete until finalized.

Authorizations:
None

Responses

Response samples

Content type
application/json
{
  • "type": "HAN_YEARLY_HISTORY_MESSAGE",
  • "x": 1735682400,
  • "t": [
    ],
  • "f": [
    ],
  • "i": [
    ],
  • "e": [
    ],
  • "c_min": [
    ],
  • "c_max": [
    ],
  • "c_avg": [
    ]
}