Webhook specification
Entrixy sends an Open command to your address and signs it. Here is the request format and how to verify the signature, so you can accept the command in your own service, smart home or board.
The request
On opening, the Entrixy server sends a POST to your webhook_url with a JSON body:
POST <your webhook_url>
Content-Type: application/json
{
"action": "open",
"object_id": 42,
"timestamp": 1750000000,
"nonce": "0011223344556677",
"signature": "9d7b58066094fa88..."
}
| Field | Value |
|---|---|
action | "open" (for bistable objects also "close") |
object_id | the object id in your account |
timestamp | unix send time, in seconds |
nonce | 16 hex characters (8 random bytes), single use |
signature | HMAC-SHA256, see below |
The fields timestamp, nonce and signature arrive only if the object has a webhook_secret. Without a secret the body carries only {action, object_id}.
The signature
What is signed is a canonical string of four dot-separated fields, not the JSON body itself, so you do not have to reproduce our serialisation byte for byte:
base = "<timestamp>.<nonce>.<action>.<object_id>" signature = HMAC-SHA256(webhook_secret, base) // hex
webhook_secret is set when you create the Webhook object in the app. Guests never receive it — the server signs with your secret itself.
How to verify it (on your side)
- Build the same string
base = timestamp.nonce.action.object_idfrom the fields you received. - Compute
HMAC-SHA256(webhook_secret, base)and compare it withsignatureusing a constant-time comparison (hash_equals/hmac.compare_digest). - Anti-replay: reject the request if
|now − timestamp| > 300seconds. Optionally, keep recentnoncevalues and reject repeats. - The signature matches and the request is fresh — perform the opening.
openssl rand -hex 32.Test vector
Run your verification against these values and check the signature:
webhook_secret = webhook_secret_example_key timestamp = 1750000000 nonce = 0011223344556677 action = open object_id = 42 base = 1750000000.0011223344556677.open.42 signature = 9d7b58066094fa88acc0afa7aa805fc5f0d008d33cb11b8aa2366102da8e20f1 = HMAC-SHA256(webhook_secret, base)
The response (optional)
Answer with 200 OK. To have the app show a result, return the JSON {"level":"success","message":"..."} (level: success/warning/danger/info). Otherwise just 200.
Ready-made receivers
curl (test send and verify), Flask and Node.js (service skeletons), Home Assistant (a webhook automation with HMAC). Relays without HMAC support (Shelly, Tasmota) connect through a proxy or Home Assistant.