Pricing FAQ Log in
EN
Start trial
How it worksBenefitsMonitorKNX AssistantTimelineChartsProjectRemote accessSitesSupported recordersPricingFAQLog in

Supported recorders › Recorder API

Recorder API.

Any device that can see KNX bus traffic can become a KNXSENSE recorder. It sends the telegrams it reads to the KNXSENSE cloud, where they are stored, analysed and made available to the installer.

This is the same interface every recorder we support today uses — Wiser for KNX, spaceLYnk, LogicMachine, ABB and Busch-Jaeger APP-Control Server, xxter, 1Home, Elsner, Raspberry Pi and Windows/macOS.

How a recorder works

Four things, and nothing else.

A recorder enrols once per installation, reads the bus, buffers what it sees and sends it on. It reads the bus and never writes to it — this interface carries telegrams out of the installation in one direction only.

If your platform supports Lua scripting, that is usually the smoothest path: several of our recorders are Lua scripts, and we can adapt one to your device. If not, the protocol below is small enough to implement in any language.

  1. EnrolRedeem a single-use install code and store the credentials
  2. ObserveTurn every telegram on the bus into a compact JSON record
  3. BufferKeep records on the device across restarts and outages
  4. SendPost batches and advance the buffer only on acknowledgement
Enrolment and authentication

One base URL, two ways to sign.

Every request goes to https://app.knxsense.com over HTTPS. All timestamps are ISO-8601 in UTC.

Enrolment

The installation owner generates a single-use install code in the KNXSENSE commissioning wizard. The device redeems it once:

POST /api/v1/asenna/asetukset
Content-Type: application/json

{ "koodi": "<install-code>", "alusta": "<your-platform-id>" }

koodi is the install code. alusta is a short platform identifier we agree with you during onboarding; your device includes it in the enrolment request, and there is no separate endpoint to fetch it. On success the server returns the device’s long-lived credentials: hub_id (a UUID identifying this recorder), token (a bearer token) and hmac_secret (a 32-byte secret, 64 hex characters, for request signing). Store all three persistently — they are per-device and can be revoked individually.

Authentication

Every request carries X-Hub-Id: <hub_id>. Two schemes are accepted, and HMAC takes precedence if both are present.

The simpler one is Authorization: Bearer <token>, which relies on TLS for confidentiality. HMAC is recommended:

X-Hub-Id:    <hub_id>
X-Timestamp: <unix-seconds>
X-Signature: sha256=<hex>

signature   = HMAC_SHA256( hmac_secret, timestamp + "." + raw_body )
X-Signature = "sha256=" + hex(signature)

The signature covers the raw request body. Sign the exact bytes you send: do not re-serialize or reorder keys after signing.

The accepted time window is ±300 seconds. If your clock falls outside it, the response is 401 with the server time in the X-Palvelimen-Aika header and in the body, so the device can correct its offset and sign again.

Sending telegrams

Batches of up to 2000 telegrams.

Telegrams are posted to /api/v1/ingest as a single JSON object — a batch. A batch holds at most 2000 telegrams and 4 MB. Delivery is at-least-once: keep resending a batch until it is acknowledged, and the server silently ignores records it has already stored.

Cadence. Send a batch as soon as it fills, or at least once a minute if it has not — the reference recorders send on a ~60-second heartbeat even when the queue is empty, which also keeps the health view current.

Batch object

FieldTypeRequiredRangeDescription
boot_idUUID✓—A new UUID generated each time the recorder process starts.
capture_srcint✓1–6How the bus was observed — see Capture modes below.
eventsarray✓≤ 2000The telegrams.
script_versionstring—Your recorder’s version.
overflowsarray—Timestamps of moments when the local queue overflowed and an unknown number of records was lost.
katkotarray—Intervals during which the recorder was not listening to the bus. (The field name is Finnish; it is part of the wire format.)
hbobject—Heartbeat — device state sent in the same request. Recommended.

Telegram object

Field names are single letters to keep bandwidth low — even a single-family home can produce hundreds of thousands of telegrams per day (the default daily limit is 1 000 000). A minimal telegram is { "q": …, "t": …, "d": … }.

FieldTypeRequiredRangeDescription
qint✓0 … 262Monotonic sequence number within the current boot_id.
tdatetime✓—Edge timestamp: ISO-8601, UTC, milliseconds.
dint✓0 … 65535Destination group address, raw. 512 is 0/2/0.
aint0 … 1023APCI. 0 = read, 1 = response, 2 = write (default).
sint0 … 65535Source individual address, raw. 0 means the recorder itself.
rstring≤ 512Raw payload bytes as a hex string. Recommended — see below.
dlint0 … 254Payload length in bytes. 0 means the value is carried in the APCI byte.
dpstring≤ 64Datapoint type if known, for example DPST-1-1 or DPT-9.
vfloat—Numeric value. Fallback only.
vtstring≤ 512Textual value. Fallback only.
ostring≤ 16Origin: bus, or us when the recorder sent it.
yint0 … 65535Gateway id. Only if you observe the same bus through more than one KNX/IP gateway, so duplicates can be reconciled. Omit otherwise.

Send the raw bytes. Values are decoded on the server from the raw payload in r, using the project’s datapoint types; v and vt are only a fallback. Sending r keeps the history re-decodable if the project definitions change later.

Raw-address alternative. If it is easier on your platform, you may send human-readable fields instead and let the server convert them: ga (1/3/5), pa (1.1.5), dpt (9.001), tt (telegram type 0/1/2), and sz with r. For a new implementation the single-letter fields above are preferred: they are unambiguous and lighter.

KNX Data Secure telegrams are stored with their addresses and raw bytes. The encrypted value is not decoded.

Acknowledgement and reliability

Advance the buffer on ack_seq, not on 200.

A 200 response returns an acknowledgement object:

FieldDescription
ack_seqThe highest sequence number durably stored. Advance your buffer only up to this.
acceptedNumber of telegrams stored.
duplicatesNumber of already-seen sequence numbers in the batch.
throttledtrue if the daily limit was reached and the batch was not stored.
lukittutrue if the account is inactive and no data is being collected. (Finnish for “locked”.)

throttled and lukittu are not acknowledgements. Keep the data buffered and retry later.

  • Sequence numbers. q must be strictly monotonic within a boot_id. Generate a fresh boot_id on restart, which also resets the counter; resends are de-duplicated automatically. The 262 ceiling is a deliberate sanity bound well below the signed 64-bit range and is never reached in practice.
  • Daily limit. Each recorder has a daily telegram limit, 1 000 000 by default, counted in the installation’s local timezone. When it is reached the batch is rejected with throttled: true and ack_seq does not advance. The data flows once the limit resets at local midnight.
  • Buffer on the device. Persist the queue with its boot_id and q so it survives restarts, and resend unacknowledged batches. If your own queue overflows, drop the oldest records and report the moment in overflows.
  • Keep the clock reasonable (NTP). Timestamps far from server time, or jumping backwards, are flagged.

Response codes

CodeMeaning
200Batch processed. Read the acknowledgement body for the result.
401Authentication failed. See the clock-skew case above.
422The body did not match the schema. Fix the record shape; do not retry it unchanged.
500Transient server error. Resend the same batch.

A single malformed record does not fail the whole batch: the valid records are kept.

Heartbeat

Send device state in the hb field of the same request: current clock, queue depth and size, dropped count, IP address and KNX link state. The heartbeat is what lets KNXSENSE show the recorder as healthy and warn the installer when it falls silent or its queue starts to grow.

Capture modes

Tell us how you read the bus.

capture_src tells KNXSENSE how the telegrams were captured:

ValueModeDescription
1Event-basedFrom the device’s own decoded event stream.
2ResidentA continuously running script on the device reads the bus.
3Bus monitorRaw frames straight from the bus.
4WebSocketFrom a WebSocket feed the device exposes.
5KNXnet/IP tunnellingThrough a tunnelling connection to a KNX/IP gateway.
6KNXnet/IP routingFrom the multicast group a KNX/IP router sends to.

Choose whatever gives the complete bus stream with correct raw payloads. If your device already decodes the bus internally, emit from that stream. If it has a KNX/IP gateway, read through tunnelling or routing. A raw bus-monitor feed is ideal, because it preserves everything — write, read and response telegrams, raw bytes and secure frames — without lossy pre-decoding.

Getting started

Four steps to a supported device.

  1. Tell us what your device can run — Lua, another language, or a firmware you extend — and how it sees the bus. We pick the lightest path together, adapting an existing Lua recorder where we can.
  2. We issue a test installation and an install code. Your device enrols and streams to a staging recorder.
  3. We confirm the round-trip together: telegrams arrive, ack_seq advances, and the heartbeat shows a healthy link.
  4. Once your integration passes our compatibility check, your product gets its own page on knxsense.com/recorders and may be marketed as KNXSENSE-compatible under our brand-use terms.

Write to support@knxsense.com to start.