This document describes the WebSocket API for the Matter.js server. The server listens on ws://localhost:5580/ws by default.
On connection, the server immediately sends a server_info message with fabric and capability information:
{
"fabric_id": 1234567890,
"compressed_fabric_id": 9876543210,
"schema_version": 11,
"min_supported_schema_version": 11,
"sdk_version": "matter.js/0.11.0",
"wifi_credentials_set": true,
"thread_credentials_set": false,
"bluetooth_enabled": true
}All commands follow this request format:
{
"message_id": "unique-id",
"command": "command_name",
"args": { ... }
}Successful responses:
{
"message_id": "unique-id",
"result": { ... }
}Error responses:
{
"message_id": "unique-id",
"error_code": 0,
"details": "Error description"
}server_info - Get server information
{
"message_id": "1",
"command": "server_info"
}diagnostics - Get server diagnostics (info, nodes, and recent events)
{
"message_id": "1",
"command": "diagnostics"
}start_listening - Start receiving events and get all nodes
When the start_listening command is issued, the server returns all existing nodes. From that moment on, all events (including node attribute changes) will be forwarded to this WebSocket connection.
{
"message_id": "1",
"command": "start_listening"
}get_nodes - Get all commissioned nodes
{
"message_id": "1",
"command": "get_nodes",
"args": {
"only_available": false
}
}get_node - Get a single node by ID
{
"message_id": "1",
"command": "get_node",
"args": {
"node_id": 1
}
}discover / discover_commissionable_nodes - Discover commissionable devices on the network
{
"message_id": "1",
"command": "discover"
}set_wifi_credentials - Set WiFi credentials for commissioning
Inform the controller about the WiFi credentials it needs to send when commissioning a new device.
{
"message_id": "1",
"command": "set_wifi_credentials",
"args": {
"ssid": "wifi-name-here",
"credentials": "wifi-password-here"
}
}set_thread_dataset - Set Thread credentials for commissioning
Inform the controller about the Thread credentials it needs to use when commissioning a new device.
{
"message_id": "1",
"command": "set_thread_dataset",
"args": {
"dataset": "hex-encoded-operational-dataset"
}
}set_default_fabric_label - Set the default fabric label
{
"message_id": "1",
"command": "set_default_fabric_label",
"args": {
"label": "Home"
}
}commission_with_code - Commission a new device using QR code or manual pairing code
For WiFi or Thread based devices, the credentials need to be set upfront, otherwise commissioning will fail. Supports both QR-code syntax (MT:...) and manual pairing code.
The controller will use Bluetooth for commissioning wireless devices. If Bluetooth is not available, commissioning will only work for devices already on the network (set network_only: true).
Using QR code:
{
"message_id": "1",
"command": "commission_with_code",
"args": {
"code": "MT:Y.ABCDEFG123456789"
}
}Using manual pairing code (network only):
{
"message_id": "1",
"command": "commission_with_code",
"args": {
"code": "35325335079",
"network_only": true
}
}commission_on_network - Commission a device already on the network
Commission using setup PIN code with optional filtering by discriminator or vendor ID.
{
"message_id": "1",
"command": "commission_on_network",
"args": {
"setup_pin_code": 20202021,
"filter_type": 2,
"filter": 3840,
"ip_addr": "192.168.1.100"
}
}Filter types:
0- No filter (discover any)1- Short discriminator2- Long discriminator3- Vendor ID
open_commissioning_window - Open commissioning window to share a device
Open a commissioning window to allow another controller to commission a device already on this controller.
{
"message_id": "1",
"command": "open_commissioning_window",
"args": {
"node_id": 1,
"timeout": 300
}
}Response includes pairing codes:
{
"message_id": "1",
"result": {
"setup_pin_code": 12345678,
"setup_manual_code": "35325335079",
"setup_qr_code": "MT:Y.ABCDEFG123456789"
}
}read_attribute - Read attribute(s) from a node
Read one or more attributes using path format endpoint/cluster/attribute. Supports wildcards using *.
Single attribute:
{
"message_id": "1",
"command": "read_attribute",
"args": {
"node_id": 1,
"attribute_path": "1/6/0"
}
}Multiple attributes:
{
"message_id": "1",
"command": "read_attribute",
"args": {
"node_id": 1,
"attribute_path": ["1/6/0", "1/6/16384", "0/40/1"]
}
}Wildcard (all attributes from OnOff cluster):
{
"message_id": "1",
"command": "read_attribute",
"args": {
"node_id": 1,
"attribute_path": "1/6/*"
}
}write_attribute - Write an attribute value
{
"message_id": "1",
"command": "write_attribute",
"args": {
"node_id": 1,
"attribute_path": "1/6/16385",
"value": 10
}
}device_command - Send a command to a device
{
"message_id": "1",
"command": "device_command",
"args": {
"node_id": 1,
"endpoint_id": 1,
"cluster_id": 6,
"command_name": "on",
"payload": {}
}
}Command with parameters (e.g., move to level):
{
"message_id": "1",
"command": "device_command",
"args": {
"node_id": 1,
"endpoint_id": 1,
"cluster_id": 8,
"command_name": "moveToLevelWithOnOff",
"payload": {
"level": 128,
"transitionTime": 10
}
}
}Optional parameters:
response_type: Set tonullto suppress response datatimed_request_timeout_ms: Timeout for timed interactions (required for some commands like door lock)
interview_node - Re-interview a node (refresh its data)
{
"message_id": "1",
"command": "interview_node",
"args": {
"node_id": 1
}
}ping_node - Ping a node to check connectivity
{
"message_id": "1",
"command": "ping_node",
"args": {
"node_id": 1,
"attempts": 3
}
}get_node_ip_addresses - Get IP addresses for a node
{
"message_id": "1",
"command": "get_node_ip_addresses",
"args": {
"node_id": 1,
"prefer_cache": false,
"scoped": false
}
}remove_node - Remove/decommission a node
{
"message_id": "1",
"command": "remove_node",
"args": {
"node_id": 1
}
}get_matter_fabrics - Get all fabrics on a node
{
"message_id": "1",
"command": "get_matter_fabrics",
"args": {
"node_id": 1
}
}remove_matter_fabric - Remove a fabric from a node
{
"message_id": "1",
"command": "remove_matter_fabric",
"args": {
"node_id": 1,
"fabric_index": 2
}
}set_acl_entry - Set ACL entries on a node
Replaces the ACL entries for the controller's fabric on the target node. The server automatically determines the fabric index.
{
"message_id": "1",
"command": "set_acl_entry",
"args": {
"node_id": 1,
"entry": [
{
"privilege": 5,
"auth_mode": 2,
"subjects": [112233],
"targets": null
}
]
}
}Entry fields:
privilege: 1=View, 3=Operate, 4=Manage, 5=Administerauth_mode: 1=PASE, 2=CASE, 3=Groupsubjects: Array of NodeIds or GroupIds (or null)targets: Optional target restrictions (or null) - each target hascluster,endpoint,device_typefields
set_node_binding - Set bindings on a node endpoint
{
"message_id": "1",
"command": "set_node_binding",
"args": {
"node_id": 1,
"endpoint": 1,
"bindings": [
{
"node": 2,
"endpoint": 1,
"cluster": 6
}
]
}
}check_node_update - Check for available firmware updates
{
"message_id": "1",
"command": "check_node_update",
"args": {
"node_id": 1
}
}update_node - Apply a firmware update
{
"message_id": "1",
"command": "update_node",
"args": {
"node_id": 1,
"software_version": 2
}
}get_vendor_names - Get vendor names by ID
{
"message_id": "1",
"command": "get_vendor_names",
"args": {
"filter_vendors": [4874, 65521]
}
}import_test_node - Import test node(s) from a diagnostic dump
Import nodes from Home Assistant diagnostic dumps for testing purposes. Test nodes have node IDs >= 0xFFFFFFFE00000000.
{
"message_id": "1",
"command": "import_test_node",
"args": {
"dump": "{\"data\":{\"node\":{...}}}"
}
}Events are sent to clients that have called start_listening. Events have this format:
{
"event": "event_name",
"data": { ... }
}node_added - A new node was commissioned or imported
{
"event": "node_added",
"data": {
"node_id": 1,
"date_commissioned": "2024-01-01T00:00:00.000000",
"last_interview": "2024-01-01T12:00:00.000000",
"interview_version": 6,
"available": true,
"is_bridge": false,
"attributes": { ... },
"attribute_subscriptions": []
}
}node_updated - A node's structure or availability changed
{
"event": "node_updated",
"data": { ... }
}node_removed - A node was decommissioned
{
"event": "node_removed",
"data": 1
}attribute_updated - An attribute value changed
{
"event": "attribute_updated",
"data": [1, "1/6/0", true]
}Format: [node_id, "endpoint/cluster/attribute", value]
endpoint_added - An endpoint was added to a node (bridges)
{
"event": "endpoint_added",
"data": {
"node_id": 1,
"endpoint_id": 3
}
}endpoint_removed - An endpoint was removed from a node
{
"event": "endpoint_removed",
"data": {
"node_id": 1,
"endpoint_id": 3
}
}node_event - A Matter event occurred (e.g., button press, switch position)
{
"event": "node_event",
"data": {
"node_id": 1,
"endpoint_id": 1,
"cluster_id": 59,
"event_id": 1,
"event_number": 12345,
"priority": 1,
"timestamp": 1704067200000,
"timestamp_type": 1,
"data": { "newPosition": 1 }
}
}server_info_updated - Server configuration changed (e.g., credentials set)
{
"event": "server_info_updated",
"data": {
"fabric_id": 1234567890,
"compressed_fabric_id": 9876543210,
"schema_version": 11,
"min_supported_schema_version": 11,
"sdk_version": "matter.js/0.11.0",
"wifi_credentials_set": true,
"thread_credentials_set": true,
"bluetooth_enabled": true
}
}server_shutdown - Server is shutting down
{
"event": "server_shutdown",
"data": {}
}Attribute paths use the format: endpoint/cluster/attribute
1/6/0- Endpoint 1, OnOff cluster (6), OnOff attribute (0)0/40/1- Endpoint 0, BasicInformation cluster (40), VendorName attribute (1)*/6/*- All endpoints, OnOff cluster, all attributes (wildcard)
| Cluster | ID | Description |
|---|---|---|
| Identify | 3 | Identify device |
| Groups | 4 | Group membership |
| OnOff | 6 | On/Off control |
| LevelControl | 8 | Dimming/level |
| Descriptor | 29 | Endpoint descriptor |
| BasicInformation | 40 | Device information |
| OtaSoftwareUpdateRequestor | 42 | OTA updates |
| ColorControl | 768 | Color/temperature |
| DoorLock | 257 | Door locks |
| WindowCovering | 258 | Blinds/shades |
| Thermostat | 513 | HVAC control |
| Code | Description |
|---|---|
| 0 | Unknown error |
| 1 | Invalid command |
| 2 | Invalid arguments |
| 3 | Node not found |
| 5 | Node does not exist |
This API is designed to be compatible with the Python Matter Server WebSocket API.
| Command | Status | Notes |
|---|---|---|
subscribe_attribute |
Stub | Not implemented (Matter.js handles subscriptions internally) |
| Field | Python | Matter.js |
|---|---|---|
MatterNode.attribute_subscriptions |
Tracks per-node subscriptions | Always empty array |
| Test node IDs | >= 900000 |
>= 0xFFFF_FFFE_0000_0000 |
- Fabric Label:
set_default_fabric_labelwith null/empty resets to "Home" instead of clearing - Attribute Subscriptions: All attributes are subscribed automatically; the
attribute_subscriptionsfield is not used - Test Nodes: Use high bigint range to prevent collision with real Matter node IDs