Agent skill

Datacake Webhooks Skill

Receive and authenticate Datacake outgoing webhooks. Use when setting up a Datacake IoT webhook endpoint, checking the secret header you add under Headers (Authorization or a custom name), debugging 401s, or handling device_measurement, decoder_output and downlink events.

Install this skill

npx skills add hookdeck/webhook-skills --skill datacake-webhooks


Datacake, the IoT platform, sends a JSON webhook to your endpoint when a device measurement is recorded, a payload decoder returns output, or a downlink is sent. Datacake webhooks are not signed. Instead you add a secret header under Headers on the webhook, and your endpoint authenticates each request by comparing that header with the value you stored.

Datacake webhooks are not signed. Add a secret header under Headers on the webhook and enter it here.

When to Use This Skill

  • How do I receive Datacake webhooks?
  • How do I authenticate a Datacake outgoing webhook? (Datacake has no signature: use a secret header)
  • How do I handle device_measurement, decoder_output or downlink events?
  • Why does my Datacake webhook endpoint return 401?
  • How do I secure a Datacake webhook that points at Node-RED or my own server?

Verification (core)

const crypto = require('crypto');

// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(received, expected) {
  const ha = crypto.createHash('sha256').update(Buffer.from(received, 'latin1')).digest();
  const hb = crypto.createHash('sha256').update(Buffer.from(expected, 'utf8')).digest();
  return crypto.timingSafeEqual(ha, hb);
}

function verifyDatacakeRequest(
  headers,
  headerName = process.env.DATACAKE_WEBHOOK_HEADER || 'Authorization',
  secret = process.env.DATACAKE_WEBHOOK_SECRET
) {
  if (!secret) return false;                          // never accept when unconfigured
  const received = headers[headerName.toLowerCase()]; // Node lowercases header names
  return typeof received === 'string' && received.length > 0 && safeEqual(received, secret);
}
  • The header name is whatever you typed under Headers in Datacake: Authorization or any custom name. Look it up case-insensitively (DATACAKE_WEBHOOK_HEADER, default Authorization).
  • Compare the whole value (DATACAKE_WEBHOOK_SECRET) exactly as typed in Datacake. If you entered Bearer ABC123, the secret is Bearer ABC123. Don't strip or parse a Bearer prefix.
  • Python: hmac.compare_digest on bytes (encode both sides; passing str raises on non-ASCII).
  • Return 401 on a missing or mismatched header, 400 for a body that isn't a JSON object, 200 once handled.
  • Read the body raw (express.raw({ type: '*/*' })) and authenticate before parsing it.
  • A static shared secret authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS and rotate the secret if it leaks. Don't rely on IP allowlisting: Datacake's infrastructure scales dynamically, so its IPs aren't stable.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Event Types

The body is { "event": ..., "data": ... }. Dispatch on event; it is chosen per webhook under Events to send.

EventSent Whendata
device_measurementNew measurement values are recorded in the databaseArray of { field, value, device, timestamp } for the fields in the last message only
decoder_outputA payload decoder returns output (raw, including values not stored)Object with result (array of { field, value, device }), log, device, product, execution_time
downlinkA downlink is sent to a LoRaWAN or MQTT device (manual or via rules)Object with meta (type, fport, downlink), device, payload (base64), product_id, product_slug

Environment Variables

DATACAKE_WEBHOOK_HEADER=Authorization            # the header name you added under Headers
DATACAKE_WEBHOOK_SECRET=Bearer your-long-token   # the exact, whole header value

Local Development

Datacake can't reach localhost. Tunnel with the Hookdeck CLI (no account required):

npx hookdeck-cli listen 3000 datacake --path /webhooks/datacake

Use the printed URL as the Endpoint URL of the webhook in Datacake.

Resources


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 10, 2026

View on GitHub →