How webhook delivery works
UniFi sends an HTTPPOST request to your configured endpoint each time a network event occurs. The payload is a JSON object describing the event type, the affected site, a timestamp, and any relevant data. The server validates the request using an HMAC-SHA256 signature before passing the event to the appropriate handler.
The webhook endpoint is registered at /webhooks/unifi by default.
Setting WEBHOOK_SECRET
The WEBHOOK_SECRET environment variable controls signature verification. UniFi signs each outgoing webhook payload using HMAC-SHA256, and the server checks the X-UniFi-Signature header against a locally computed signature using your secret.
Always set
WEBHOOK_SECRET in production. Without it, the server accepts webhook payloads from any source. An attacker could send forged events to manipulate cached state or trigger handlers. The secret must match the value you configure in your UniFi controller’s webhook settings.Event types
The server includes built-in handlers for the following event categories:
Event types follow the format
category.action. You can also register wildcard handlers using category.* to catch all events within a category.
Webhook payload structure
Every incoming webhook payload follows this structure:data object includes fields such as mac, hostname, and essid (the SSID the client was connected to). For alert events, data includes type, message, and severity.
Setting up the webhook endpoint
1
Set your webhook secret
Add
WEBHOOK_SECRET to your .env file or environment. Choose a long, random string.2
Expose the endpoint
The MCP server must be reachable from your UniFi controller. If you are running locally, use a tool like ngrok to create a public tunnel:This gives you a public HTTPS URL such as
https://abc123.ngrok.io.3
Configure UniFi to send webhooks
In your UniFi controller, navigate to Settings → Notifications → Webhooks and add your endpoint URL:Enter the same secret string you set in
WEBHOOK_SECRET.4
Verify delivery
Check your server logs for incoming events. A successful delivery looks like:
Signature verification details
The server computes the expected signature as:X-UniFi-Signature header using a constant-time comparison to prevent timing attacks. Requests with a missing or invalid signature are rejected with 401 Unauthorized.
Automatic cache invalidation
When a webhook event arrives, the built-in handlers automatically invalidate the relevant Redis cache entries. For example:device.onlineanddevice.offline→ invalidates the devices cache for that siteclient.connectedandclient.disconnected→ invalidates the clients cache for that site
Rate limiting
The webhook receiver limits incoming requests to 100 events per minute per site. Requests exceeding this threshold receive a429 Too Many Requests response. Duplicate events (identified by event_id) within a 5-minute window are silently discarded.