# Stop polling. Get notified instantly.

Your fleet is making millions of API calls a day just to check if routers are online. Webhooks push that information to you the moment something changes.

#### ❌ Polling every 60 seconds

1,000 routers × 1 call/min × 60 min × 24 hrs

**1.44M calls/day**

Delayed detection. Wasted API calls. Rate-limit pressure.

#### ✓ Webhook on state change

Only fires when a router actually goes online or offline.

**~50 calls/day**

Instant notification. Zero wasted calls. Real-time awareness.

## Why webhooks are the foundation for modern network operations

Webhooks aren't just about reducing API calls. They're the event layer that enables everything from simple alerting to fully autonomous network management.

**The shift:** Polling asks “what happened?” Webhooks tell you “something is happening.” That difference is what separates reactive network management from proactive, AI-driven operations. Every automation workflow, every AI agent, every real-time dashboard starts with an event — and webhooks are how NCM delivers those events to your systems.

## How webhooks work

NCM webhooks are built on the alert system. You create an HTTP destination (your server), configure alert rules for the events you care about, and NCM pushes a notification to your URL when those events fire.

- **Create a destination** — tell NCM where to send notifications (your URL + a shared secret)
- **Test the destination** — verify NCM can reach your server
- **Create an alert rule** — pick which events trigger notifications
- **Link the destination** — attach your HTTP destination to the alert rule
When an event fires, NCM sends an HTTP POST to your URL with the alert payload. Your server validates the request using the shared secret and processes the event.

## Setup guide

### Step 1 — Create a webhook destination

Register your server URL with NCM. The secret verifies that incoming webhooks are actually from NCM. Or do it in the NCM UI: **Alerts & Logs &rarr; Push Destinations &rarr; Add Destination**. Save the `destination_config_id` from the response — you'll need it in Step 3.

 
```
POST https://www.cradlepointecm.com/api/v2/alert_push_destinations/

{
  "name": "My Monitoring Server",
  "address": "https://my-server.example.com/webhooks/ncm",
  "secret": "your-shared-secret-here",
  "enabled": true
}
```
 

### Step 2 — Test the destination

Verify NCM can reach your server before configuring alert rules. A `201 Created` response with an empty body means your destination is reachable and the secret is valid.

 
```
POST https://www.cradlepointecm.com/api/v2/test_alert_push_destinations/

{
  "destination_config_id": "YOUR_DESTINATION_CONFIG_ID",
  "secret": "your-shared-secret-here"
}
```
 

### Step 3 — Create an alert rule with your destination

Configure which events trigger notifications and where they're sent. Or in the NCM UI: **Alerts & Logs &rarr; Alert Rules &rarr; Add Rule** → select alert types → add your HTTP destination.

 
```
POST https://www.cradlepointecm.com/api/v2/alert_rules/

{
  "name": "Router Online/Offline Alerts",
  "alert_types": ["online_offline_alert"],
  "http_destinations": ["YOUR_DESTINATION_CONFIG_ID"],
  "enabled": true
}
```
 

### Step 4 — Receive and verify webhooks

When an alert fires, NCM sends an HTTP POST to your destination URL. Verify the request using the shared secret.

 
```
from flask import Flask, request, jsonify

app = Flask(__name__)
SHARED_SECRET = "your-shared-secret-here"

@app.route("/webhooks/ncm", methods=["POST"])
def handle_webhook():
    payload = request.json
    alert_type = payload.get("alert_type")
    router_name = payload.get("router_name", "Unknown")
    if alert_type == "online_offline_alert":
        state = payload.get("state", "unknown")
        print(f"Router {router_name} is now {state}")
    return jsonify({"status": "ok"}), 200

if __name__ == "__main__":
    app.run(port=5000)
```
 

## Available alert types

These are the event categories you can subscribe to. Each category contains multiple specific alert types and links to its full definitions, thresholds, and example messages.

| Category | What it covers | Common use case |
| --- | --- | --- |
| General | Device online/offline, device registered, device unregistered | Fleet uptime monitoring — replaces polling |
| Health | Cellular health score changes, connection quality degradation | Proactive network quality monitoring |
| Modem | Signal strength thresholds, carrier changes, SIM events | Cellular connectivity monitoring |
| Configuration | Config push, config rejected, config drift | Change management, compliance |
| Security | Unauthorized access attempts, certificate events | Security monitoring, SIEM integration |
| Carrier Data | Pooled data usage thresholds, per-router usage percentage | Cost management |
| Carrier Selection | CSI test started/passed/failed/error | Connectivity resilience monitoring |
| Ethernet | Ethernet link up/down, speed changes | WAN monitoring |
| Hardware | Hardware failures, critical operating temperature | Device health monitoring |
| Battery | Battery health, over current/temp/voltage, low power, power off, maintenance cycles, backup power, wall power restored | E100/E400/X20 battery monitoring |
| LAN | LAN interface events | Local network monitoring |
| Location Services | Geofence enter/exit, GPS events | Fleet tracking, geofencing |
| Cellular Access Points | AP reboot, NTP sync issues, radio status, AP/core connection state, high temp, SAS grant events, IPsec tunnel failure | Private cellular monitoring |
| Mobility Gateway | Mobility gateway events | Mobile network monitoring |
| NetCloud OS Apps | SDK app events | App lifecycle monitoring |
| Subscriptions | License expiration, subscription changes | License management |
| Wi-Fi as WAN | Wi-Fi WAN connection events | Alternative WAN monitoring |
| Service Gateway | Service gateway events | Gateway monitoring |
| AI Insights | AI-generated network recommendations | Proactive optimization |
See the complete [Alerting and Reporting documentation](https://docs.cradlepoint.com/r/Alerting-and-Reporting-with-NCM/) for details.

## Common recipes

### 🔴 Alert me when any router goes offline

This is the #1 reason customers poll. Replace it with a single alert rule.

 
```
# 1. Create destination (one-time setup)
POST /api/v2/alert_push_destinations/
{"name": "NOC Dashboard", "address": "https://noc.example.com/hooks", "secret": "s3cret", "enabled": true}

# 2. Create alert rule for online/offline
POST /api/v2/alert_rules/
{"name": "Fleet Online/Offline", "alert_types": ["online_offline_alert"], "http_destinations": ["DEST_CONFIG_ID"], "enabled": true}
```
 

### 📶 Alert me when signal drops below -90 dBm

Instead of polling `net_device_signal_samples`, set a threshold alert.

 
```
POST /api/v2/alert_rules/
{
  "name": "Low Signal Alert",
  "alert_types": ["signal_strength_alert"],
  "threshold": -90,
  "http_destinations": ["DEST_CONFIG_ID"],
  "enabled": true
}
```
 

### ⚙️ Alert me when a config change is pushed

Track configuration changes across your fleet without polling `configuration_managers`.

 
```
POST /api/v2/alert_rules/
{
  "name": "Config Change Tracking",
  "alert_types": ["config_push_alert", "config_rejected_alert"],
  "http_destinations": ["DEST_CONFIG_ID"],
  "enabled": true
}
```
 

### 🔌 Alert me on carrier failover

Know immediately when a device switches from primary to backup WAN.

 
```
POST /api/v2/alert_rules/
{
  "name": "Failover Alerts",
  "alert_types": ["failover_alert"],
  "http_destinations": ["DEST_CONFIG_ID"],
  "enabled": true
}
```
 

## Integration examples

### ServiceNow

Auto-create an incident when a device goes offline.

 
```
import requests

def handle_ncm_webhook(payload):
    if payload.get("alert_type") == "online_offline_alert":
        if payload.get("state") == "offline":
            requests.post("https://your-instance.service-now.com/api/now/table/incident",
                json={
                    "short_description": f"Router {payload['router_name']} went offline",
                    "urgency": "2",
                    "category": "Network"
                },
                auth=("admin", "password")
            )
```
 

### Slack

Post to a channel on any alert.

 
```
import requests

SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"

def handle_ncm_webhook(payload):
    router = payload.get("router_name", "Unknown")
    alert = payload.get("alert_type", "unknown")
    requests.post(SLACK_WEBHOOK, json={
        "text": f"🚨 NCM Alert: *{alert}* on router *{router}*"
    })
```
 

## API reference

Webhooks are configured through these v2 API endpoints:

- **alert_push_destinations** — create and manage HTTP destinations (your webhook URLs)
- **alert_rules** — configure which events trigger notifications
- **test_alert_push_destinations** — test that NCM can reach your destination
- **alerts** — view alerts that have been generated
- **router_alerts** — view device-specific alerts
Authentication for these endpoints uses the v2 API key headers (`X-CP-API-ID`, `X-CP-API-KEY`, `X-ECM-API-ID`, `X-ECM-API-KEY`).

**Firewall configuration:** if your webhook destination is behind a firewall, allowlist NCM's outbound IP addresses (see the alert_push_destinations documentation for the current list).

[Browse the full API reference →](/developer/api)
