Skip to main content

REST API & webhooks

On the Pro plan and above you can integrate KNX Clarity with your own systems: pull data over a read-only REST API, and receive webhooks when things change. Both are managed under Settings.

Plan requirement

The REST API and webhooks are Pro / Enterprise features — see Plans & billing. Pro includes up to 5 API keys and 5 webhooks; Enterprise raises both to 50.

API keys

Open Settings → API-Schlüssel and click Neuer API-Key. Give it a name and an expiry (never, 30 days, 90 days, or 1 year). The key is issued with the four read scopes — me:read, projects:read, devices:read, groupaddresses:read. Write access is not available yet.

The plaintext token (kx_…) is shown exactly once at creation — copy it then, because only a hash is stored and it can never be shown again. Revoke a key any time with the trash icon; the row stays for the audit trail but the token stops working immediately.

Using the REST API

Send the token as a bearer header:

Authorization: Bearer kx_your_token_here

The base URL is issued per environment (the RestApiUrl value for your stack). Every response is scoped to the token's organisation — you never pass an org id. Endpoints:

Method & pathScopeReturns
GET /v1/healthnone{ "ok": true }
GET /v1/meme:readthe org, the user, and the key
GET /v1/projectsprojects:read{ items, count } (up to 100)
GET /v1/projects/:idprojects:reada single project

Errors come back as { "error": { "code", "message" } } — a 401 for a missing/invalid/expired key, a 403 (scope_required) when the key lacks the scope. The API is intentionally minimal for now: read-only, no pagination, no per-key rate limiting, no CORS.

Webhooks

Open Settings → Webhooks and click Neuer Webhook. Provide a name, an HTTPS endpoint URL, and the events to subscribe to:

  • project.created, project.updated, project.archived
  • service_case.created, service_case.status_changed

A signing secret (whsec_…) is shown once at creation. Use the Test-Event senden button to fire a webhook.test delivery while you build your receiver.

Payloads and signatures

Each delivery is a POST with these headers:

  • X-KNX-Event — the event type.
  • X-KNX-Delivery — a per-attempt UUID (use it as an idempotency key).
  • X-KNX-Signaturet=<unix-seconds>,v1=<hex>, a Stripe-style HMAC.

The body is JSON: { id, type, orgId, eventId, createdAt, triggeredByUserId, data }.

To verify a delivery, compute the HMAC over "<t>.<rawBody>". The HMAC key is the SHA-256 hash (hex) of your signing secret, not the secret itself:

import crypto from "node:crypto";

function verify(signingSecret, header, rawBody) {
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
const key = crypto.createHash("sha256").update(signingSecret).digest("hex");
const expected = crypto
.createHmac("sha256", key)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const ok = crypto.timingSafeEqual(
Buffer.from(parts.v1),
Buffer.from(expected)
);
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return ok && fresh;
}

Reject anything where the signature doesn't match or the timestamp is more than a few minutes old (replay protection).

Retries and auto-disable

A delivery is attempted up to 3 times (immediately, after 5 s, after 30 s). Network errors, 5xx, and 429 are retried; any other 4xx is treated as permanent. If a webhook fails 5 batches in a row it is automatically disabled and the creator is notified — re-enable it with Aktivieren once your endpoint is healthy. Every attempt is recorded in the delivery log (Zustellungen anzeigen), kept for 30 days.