Guide to Enode Webhooks: Features and Best Practices
Enode webhooks notify your systems about connected energy-device activity: an EV's state updates, a charger changes, a battery reports. If you're building on Enode's energy API, webhooks are how you react to device changes without polling.
This guide covers how Enode webhooks work, the events you'll handle, how to verify the x-enode-signature (it's HMAC-SHA1, not SHA256), the retry behavior, and the best practices for production.
What are Enode webhooks?
Enode webhooks are HTTP POSTs delivered to a URL you register, each signed. The signature detail that trips people up: Enode uses HMAC-SHA1, not SHA256. The x-enode-signature header is sha1=<hex>, and the secret is one you generate and supply at creation (Enode doesn't return it).
Enode webhook features
| Feature | Details |
|---|---|
| Configuration | POST /webhooks with url, secret, events, optional auth header/value |
| Signature header | x-enode-signature, formatted sha1=<hex> |
| Signature scheme | HMAC-SHA1 over the raw UTF-8 body |
| Secret | Caller-supplied at creation (min 128 bits); not returned by Enode |
| Event format | colon-delimited (e.g. user:vehicle:updated) |
| Retries (production) | Over 24h with increasing intervals, then deletes pending events and marks the webhook inactive |
| Retries (sandbox) | Marks inactive after ~5 min of failures |
| SDK | None |
Common events
Enode event names are colon-delimited:
| Event | Fires when |
|---|---|
user:vehicle:updated | A user's vehicle state updates |
user:charger:updated | A user's charger updates |
user:battery:updated | A user's battery updates |
system:heartbeat | A periodic heartbeat |
enode:webhook:test | A test event |
Subscribe to the events you process (in the events array at creation), and consult Enode's webhook reference for the full catalog.
Setting up Enode webhooks
Create a webhook with POST /webhooks, providing url, a secret you generate (minimum 128 bits), the events array, and optional custom auth header/value. Enode doesn't return the secret, so store it when you create the webhook. Use the Test and Update (/webhooks/{id}) endpoints to reactivate an inactive webhook.
Securing Enode webhooks
Each delivery carries an x-enode-signature header formatted sha1=<hex>, a lowercase-hex HMAC-SHA1 of the raw UTF-8 body, keyed with your supplied secret. Compute over the exact raw bytes and compare in constant time.
const crypto = require("crypto");
const SECRET = process.env.ENODE_WEBHOOK_SECRET; // you generated this
function verify(rawBody, signatureHeader) {
const expected = "sha1=" +
crypto.createHmac("sha1", SECRET).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
if (!verify(req.body, req.headers["x-enode-signature"])) {
return res.sendStatus(401);
}
res.sendStatus(200); // acknowledge fast
processQueue.add(JSON.parse(req.body)); // process asynchronously
});
The same check in Python:
import hashlib
import hmac
import os
SECRET = os.environ["ENODE_WEBHOOK_SECRET"].encode()
def verify(raw_body: bytes, signature_header: str) -> bool:
expected = "sha1=" + hmac.new(SECRET, raw_body, hashlib.sha1).hexdigest()
return hmac.compare_digest(expected, signature_header or "")
Enode webhook limitations and pain points
It's SHA1, not SHA256
The Problem: Enode uses HMAC-SHA1. Reaching for SHA256 (the default for most webhooks) fails every delivery.
Why It Happens: Enode's scheme predates the SHA256 conventions many newer providers adopted.
Workarounds:
- Use
sha1explicitly and compare against thesha1=header over the raw body.
How Hookdeck Can Help: Hookdeck verifies the x-enode-signature HMAC-SHA1 at the edge, so your app receives pre-verified events without special-casing the algorithm.
You generate and hold the secret
The Problem: Enode doesn't return the secret; you supply it at creation. Lose it and you can't verify without recreating the webhook.
Why It Happens: Enode has you provide the signing secret rather than issuing one.
Workarounds:
- Generate a strong secret (>=128 bits), store it securely at creation, and reuse it for verification.
How Hookdeck Can Help: Hookdeck verifies at the edge, so the secret lives in one place rather than in every handler.
Failure leads to inactivation and event loss
The Problem: In production, Enode retries over 24 hours, then deletes pending events and marks the webhook inactive; sandbox inactivates after ~5 minutes. A sustained outage loses events and switches the webhook off.
Why It Happens: Enode prunes persistently failing webhooks.
Workarounds:
- Acknowledge fast so transient issues don't accumulate; monitor webhook state and reactivate via the API; reconcile via the API for anything critical.
How Hookdeck Can Help: Hookdeck always accepts deliveries and absorbs downstream failures itself, keeping the webhook active while it retries to your service.
Duplicates
The Problem: Retries mean the same event can arrive more than once.
Why It Happens: At-least-once delivery favors eventual delivery.
Workarounds:
- Dedupe on an event id and make side effects idempotent.
How Hookdeck Can Help: Hookdeck deduplicates deliveries at the edge. See our guide to webhook idempotency.
Best practices
Verify HMAC-SHA1 over the raw body
Use sha1, compute over the raw UTF-8 body with your supplied secret, and compare against the sha1= header in constant time.
Store the secret at creation
Generate a strong secret and keep it; Enode won't return it later.
Acknowledge fast and monitor state
Return 200 quickly, process off a queue, and watch for inactivation so you can reactivate. See why to process webhooks asynchronously.
Dedupe
Dedupe on an event id so retries don't double-process.
Make Enode webhooks production-ready
Hookdeck verifies x-enode-signature (SHA1), deduplicates, and durably queues every device event
Conclusion
Enode webhooks verify with an x-enode-signature HMAC-SHA1 (sha1=<hex>) over the raw body, keyed with a secret you generate and store. Use SHA1 (not SHA256), keep the secret, acknowledge fast to avoid inactivation, and dedupe.
Hookdeck verifies the signature, deduplicates, and durably queues every event at the edge, so your app only ever processes verified, unique device events.
Get started with Hookdeck for free and handle Enode webhooks reliably in minutes.