Guide to Cisco Meraki Webhooks: Features and Best Practices
Cisco Meraki webhook alerts notify your systems when something happens on a Meraki network: motion is detected, a setting changes, access points go down, a sensor reading crosses a threshold. If you're building monitoring, alerting, or automation on Meraki, webhooks are how you react without polling the Dashboard API.
This guide covers how Meraki webhooks work, the alerts you'll handle, the unusual verification model (a shared secret carried in the request body, not a header), custom templates, and the best practices for production.
What are Cisco Meraki webhooks?
Meraki Dashboard sends webhook alerts as HTTP POSTs to an HTTP server (endpoint) you configure. Each payload describes an alert with a human-readable alertType and a machine-readable alertTypeId.
The verification model is what makes Meraki unusual: there's no signature header. Instead, a plaintext sharedSecret field is carried inside the JSON body, and you compare it against the secret you configured. Generic "verify the signature header" logic finds nothing to check.
Cisco Meraki webhook features
| Feature | Details |
|---|---|
| Configuration | Dashboard > Network-wide > Alerts > Webhooks / HTTP servers |
| Verification | Plaintext sharedSecret field in the JSON body (compare to your configured value) |
| Transport security | TLS (HTTPS, CA-trusted cert; no self-signed) is the real protection |
| Payload | alertType, alertTypeId, version, sentAt, occurredAt, organizationId, networkId, deviceSerial, alertData |
| Custom templates | Liquid template language; can reshape headers and body |
| Delivery | ~90s after the event; "Send test" posts a sample |
| Auto-disable | Receiver disabled after >100 failed attempts in 24h |
| Alert catalog | GET /organizations/{organizationId}/webhooks/alertTypes |
| SDK | meraki (pip) is a Dashboard-API client; no webhook verification (there's no signature) |
Common alerts
Meraki alerts pair a human label (alertType) with a machine id (alertTypeId):
| alertType | alertTypeId | Fires when |
|---|---|---|
| Motion detected | motion_alert | A camera detects motion |
| Settings changed | settings_changed | A configuration setting changes |
| Sensor change detected | sensor_alert | A sensor reading crosses a threshold |
| APs went down | stopped_reporting | Access points stop reporting |
Branch on alertTypeId (stable) rather than alertType (a display label). The live catalog for your organization is available via GET /organizations/{organizationId}/webhooks/alertTypes.
Setting up Cisco Meraki webhooks
Configure an HTTP server under Dashboard > Network-wide > Alerts > Webhooks / HTTP servers: set the URL, a shared secret, and optionally a custom payload template. Use "Send test" to post a sample. The endpoint must be HTTPS with a CA-trusted certificate (self-signed certs are rejected).
Securing Cisco Meraki webhooks
There's no signature to verify. Meraki includes the sharedSecret you configured as a field in the JSON body; compare it (in constant time) against your stored value, and rely on TLS for transport authenticity.
const crypto = require("crypto");
const SHARED_SECRET = process.env.MERAKI_SHARED_SECRET;
function secretMatches(received) {
const a = Buffer.from(received || "");
const b = Buffer.from(SHARED_SECRET);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post("/webhook", express.json(), (req, res) => {
if (!secretMatches(req.body.sharedSecret)) {
return res.sendStatus(401);
}
res.sendStatus(200); // acknowledge fast
processQueue.add(req.body); // process by alertTypeId, async
});
The same check in Python:
import hmac
import os
SHARED_SECRET = os.environ["MERAKI_SHARED_SECRET"]
@app.post("/webhook")
def webhook():
if not hmac.compare_digest(request.json.get("sharedSecret", ""), SHARED_SECRET):
return "", 401
# process by alertTypeId, async
return "", 200
Two caveats: the shared secret is optional and travels in plaintext (inside TLS), so it's a lightweight check, not a cryptographic signature; and if you enable a Liquid payload template, the body shape (and even where the secret lands) can change, so verify against your actual template output.
Cisco Meraki webhook limitations and pain points
The secret is a body field, not a signature
The Problem: There's no HMAC or signature header. Verification is a plaintext string compare on payload.sharedSecret. Any code expecting a signature header does nothing, and the secret is only as strong as TLS keeping the body confidential.
Why It Happens: Meraki's model is a shared-secret body field plus TLS, not payload signing.
Workarounds:
- Compare
payload.sharedSecretin constant time, require HTTPS with a trusted cert, and treat the check as authentication-lite.
How Hookdeck Can Help: Hookdeck gives you a dedicated ingestion URL and can enforce its own verification and filtering in front of your endpoint, adding a layer beyond a plaintext body secret.
Custom Liquid templates reshape the payload
The Problem: If a custom template is enabled, the payload (and header) structure can change completely, so code assuming the default schema, or a fixed location for sharedSecret, breaks.
Why It Happens: Meraki lets you fully reshape the payload with Liquid templates.
Workarounds:
- Verify against your actual template output, and keep the secret field in a known place if you template the body.
How Hookdeck Can Help: Hookdeck's transformations normalize payloads before they reach your app, so downstream code sees a consistent shape regardless of Meraki templates.
Auto-disable after failures
The Problem: A receiver is disabled after more than 100 failed attempts in 24 hours. A flaky endpoint silently stops receiving alerts.
Why It Happens: Meraki prunes receivers that consistently fail.
Workarounds:
- Acknowledge fast so transient issues don't accumulate; monitor receiver status and re-enable.
How Hookdeck Can Help: Hookdeck always accepts deliveries and absorbs downstream failures itself, keeping the receiver active while it retries to your service.
Delivery latency and duplicates
The Problem: Alerts arrive roughly 90 seconds after the event, and can repeat, so don't treat them as instant or exactly-once.
Why It Happens: Meraki batches and retries alert delivery.
Workarounds:
- Dedupe on
alertId/occurredAt, and design for ~90s latency.
How Hookdeck Can Help: Hookdeck deduplicates deliveries at the edge, so repeats don't double-process. See our guide to webhook idempotency.
Best practices
Compare the sharedSecret body field in constant time
Check payload.sharedSecret against your configured value with a constant-time comparison, and require HTTPS with a CA-trusted certificate.
Branch on alertTypeId
Route on the stable alertTypeId, not the human alertType label.
Account for templates
If you use a Liquid template, verify against its actual output shape.
Acknowledge fast and dedupe
Return 200 quickly, process off a queue, and dedupe so retries and the ~90s latency don't cause double-processing. See why to process webhooks asynchronously.
Make Cisco Meraki webhooks production-ready
Hookdeck adds verification beyond a body secret, normalizes templated payloads, deduplicates, and durably queues every alert
Conclusion
Cisco Meraki webhook alerts are verified not by a signature but by a plaintext sharedSecret field inside the body, with TLS as the real transport protection, and Liquid templates that can reshape the payload entirely. Compare the secret in constant time, branch on alertTypeId, account for templates, and dedupe.
Hookdeck adds verification and filtering beyond the body secret, normalizes templated payloads, deduplicates, and durably queues every alert at the edge, so your app processes trustworthy, consistent events.
Get started with Hookdeck for free and handle Cisco Meraki webhooks reliably in minutes.