Delta Sync API over websockets
Delta Sync:
A protocol that keeps a chosen set of fields in sync between a device and the cloud. Only type names, IDs, and plain typed values cross the wire, never Quantum schema encoded objects, so it keeps working across any Quantum version combination, both directions, reactively.
Auth is the device's client certificate (mTLS), and the auth group on the cert bounds what the cloud pushes down and what writes it accepts. No Quantum schema version check here.
On connect the device sends reconcile with the values that changed since its watermark and holds its live updates until the cloud confirms with the reconcile's ack. After that, both sides stream changes as they happen. A bad node or message never takes down the connection. A node the cloud can't apply comes back with its id and what went wrong. A field it can't read or doesn't recognize is logged and skipped, and the rest of the update still applies. A message it can't read at all comes back as an error saying why. The connection stays open through all of it.
Supported types and fields:
Right now Delta Sync only carries:
property
- currentValue (number)
- description (text)
Delta Sync messageTypes:
deltaUpdate: One or more changed fields on an object, batched so everything from one debounce window travels together. Device to cloud it carries a requestID and the cloud answers it with an ack, so a batch that fails can be retried. Cloud to device it is a fire and forget push with no ack. A field with a value is set, a field sent as null is cleared, and a field left out is unchanged.
ex)
{
"messageType": "deltaUpdate",
"deviceID": "<serialNumber>",
"requestID": "<uuid>",
"payload": { "updates": [
{ "property": { "id": "<uuid>", "currentValue": 72.5 } },
{ "property": { "id": "<uuid>", "description": "Supply fan" } },
{ "property": { "id": "<uuid>", "currentValue": 68.0, "description": "Zone 1 setpoint" } },
{ "property": { "id": "<uuid>", "currentValue": null } },
{ "property": { "id": "<uuid>", "description": null } }
] }
}
reconcile: Device to cloud, sent on connect. The values that changed since the device's watermark, or every synced field on the first connect. The device is the source of truth, so this is a push not a request. Carries a requestID and is answered by an ack. Same payload shape as deltaUpdate.
ex)
{
"messageType": "reconcile",
"deviceID": "<serialNumber>",
"requestID": "<uuid>",
"payload": {
"since": "2026-09-04T12:00:00Z",
"updates": [
{ "property": { "id": "<uuid>", "currentValue": 72.5, "description": "Supply fan" } }
]
}
}
ack: Cloud to device. Answers a reconcile or a device-sent deltaUpdate, echoing its requestID. errors lists the objects the cloud could not apply, each with a typed code. An empty list means everything applied. For a reconcile it also lists any property the cloud itself changed since the device's watermark, which the device then sends up, so a reconcile is two sends when the cloud has drifted and one send plus this ack when it has not. Streaming starts after the reconcile's ack.
ex)
{
"messageType": "ack",
"deviceID": "<serialNumber>",
"requestID": "<uuid>",
"payload": {
"errors": [
{ "id": "<uuid>", "code": "notFound", "message": "Property not present in the cloud." }
],
"changed": ["<uuid>"]
}
}
error: Either direction. Something was rejected, e.g. bad auth or an unknown message.
ex)
{
"messageType": "error",
"deviceID": "<serialNumber>",
"payload": { "code": "unauthorized", "message": "..." }
}
Request
- Base URLhttps://passivelogic.com (the document declares no server; this is the origin it was published from)
- Auth
- API key in header X-PL-AUTH
- or API key in header Authorization: PL-API-KEY
- or API key in header PL-API-KEY
- or HTTP basic
- TypeScriptA function with typed inputs. Its response is checked against the schema.
Changes
No recorded changes to this operation across all 1 revision of this API.