- Add MorningSummaryService with Zabbix aggregation and adaptive card builder - Add webhook delivery system with Teams incoming webhooks - Add admin UI at /admin/morning-summary for webhook/config management - Add API routes: /send, /test, /webhooks, /webhooks/[id], /config, /history - Register morning-summary cron job in SyncScheduler (Mon-Fri 6:30 AM) - Add outages_only filter (Unavailable triggers only) - Fix host resolution: use getTriggerEnabledHosts to exclude disabled hosts - Fix resolved events: event.get value:1 scoped to window with r_eventid filter - Remove emojis from fact rows and section headers in card - Remove Open Zabbix button (duplicate of View Problems) - Add migrations: morning_summary_config + morning_summaries tables - Add outages_only column to morning_summary_config
26 KiB
Windsurf + Sonnet Development Guide — Zabbix Monitoring System
For: AI-assisted development in Windsurf using Claude Sonnet 4.6 Organization: Wulf Consulting (MSP) Last updated: 2026-03-11
Table of Contents
- System Overview
- Infrastructure & Network Topology
- Zabbix API Reference
- Host Organization & Data Model
- Notification Pipeline
- Trigger Naming Conventions
- Grafana Integration
- Pulse Integration Architecture
- Development Patterns & Gotchas
- API Cookbook
1. System Overview
Wulf Consulting is an MSP managing ~46 client sites. The monitoring stack runs on a single Ubuntu 24.04 server (public IP: 209.166.162.245) with all services containerized in Docker.
Stack Components
| Service | Container | Image | Purpose |
|---|---|---|---|
| Zabbix Server | zabbix-server |
zabbix/zabbix-server-pgsql:alpine-7.4-latest |
Core monitoring engine |
| Zabbix Frontend | zabbix-frontend |
zabbix/zabbix-web-nginx-pgsql:alpine-7.4-latest |
Web UI + API endpoint |
| PostgreSQL | zabbix-postgres |
postgres:17-alpine |
Zabbix database |
| Grafana | grafana |
grafana/grafana:latest |
Dashboards + Zabbix plugin |
| ntfy | ntfy |
binwiederhier/ntfy:latest |
Push notification server |
| Apprise | apprise-api |
caronc/apprise:latest |
Multi-channel notification router |
| Authentik | authentik |
ghcr.io/goauthentik/server:2025.8.1 |
SSO/identity provider |
| Newt | newt |
fosrl/newt |
Pangolin tunnel agent |
External Access
All services are exposed through Pangolin (reverse proxy/tunnel), not direct port mappings.
| Service | External URL |
|---|---|
| Zabbix | https://zabbix.wulfconsulting.cloud |
| Grafana | (via Pangolin — check Pangolin config for exact URL) |
SSO is handled by Authentik with SAML integration to Zabbix.
Software Versions
- Zabbix: 7.4.7
- PostgreSQL: 17 (Alpine)
- Grafana: Latest (with
alexanderzobnin-zabbix-app6.2.1) - Host OS: Ubuntu 24.04.4 LTS
2. Infrastructure & Network Topology
Docker Networks
┌─────────────────────────────────────────────────────────────┐
│ pangolin (172.18.0.0/16) │
│ ┌─────────────┐ ┌──────────┐ ┌──────┐ ┌───────────────┐ │
│ │zabbix-front │ │ grafana │ │ ntfy │ │ apprise-api │ │
│ │ 172.18.0.4 │ │172.18.0.3│ │.0.7 │ │ 172.18.0.5 │ │
│ └──────┬──────┘ └────┬─────┘ └──────┘ └───────────────┘ │
│ │ │ │
│ ┌──────┴──────┐ │ ┌──────────┐ ┌───────────┐ │
│ │zabbix-server│ │ │authentik │ │ newt │ │
│ │ 172.18.0.8 │ │ │172.18.0.6│ │172.18.0.2 │ │
│ └──────┬──────┘ │ └──────────┘ └───────────┘ │
│ │ │ │
└─────────┼──────────────┼─────────────────────────────────────┘
│ │
┌─────────┼──────────────┼──────────────────────┐
│ │ zabbix_zabbix_internal (172.19.0.0/16) │
│ ┌──────┴──────┐ ┌────┴─────┐ ┌──────────────┐│
│ │zabbix-server│ │ grafana │ │zabbix-frontend││
│ │ 172.19.0.4 │ │172.19.0.3│ │ 172.19.0.5 ││
│ └─────────────┘ └──────────┘ └──────────────┘│
│ ┌──────────────┐│
│ │zabbix-postgres││
│ │ 172.19.0.2 ││
│ └──────────────┘│
└─────────────────────────────────────────────────┘
Key Connectivity Facts
- Zabbix API (internal):
http://zabbix-frontend:8080/api_jsonrpc.php— accessible fromzabbix-server,grafana, and anything onzabbix_zabbix_internal - Zabbix API (external):
https://zabbix.wulfconsulting.cloud/api_jsonrpc.php— via Pangolin - ntfy (internal):
http://ntfy:80— accessible fromzabbix-serverandzabbix-frontendviapangolinnetwork - Apprise API:
http://apprise-api:8000(also0.0.0.0:8000on host) - Zabbix agent port:
10051(mapped to host0.0.0.0:10051) - Grafana has NO external port mapping — accessed only through Pangolin
Docker Compose Location
All stack definitions: /opt/stacks/zabbix/compose.yml
Environment variables: /opt/stacks/zabbix/.env
3. Zabbix API Reference
Authentication
Zabbix 7.4 uses Bearer token authentication:
Authorization: Bearer <api_token>
API tokens are generated in Zabbix UI: User Settings → API tokens
Important: The
apiinfo.versionmethod MUST be called WITHOUT the Authorization header. All other methods require it.
Base Request Format
{
"jsonrpc": "2.0",
"method": "<method_name>",
"params": { ... },
"id": 1
}
API Endpoint
| Context | URL |
|---|---|
From zabbix-server or grafana container |
http://zabbix-frontend:8080/api_jsonrpc.php |
| From the Docker host | docker exec zabbix-frontend curl -s -X POST http://localhost:8080/api_jsonrpc.php ... |
| From external / Pulse | https://zabbix.wulfconsulting.cloud/api_jsonrpc.php |
Key API Methods Used
| Method | Purpose | Notes |
|---|---|---|
host.get |
List hosts, get groups/templates | Use selectHostGroups, selectParentTemplates |
hostgroup.get |
List host groups | Filter by Clients/ or ISP/ prefix |
trigger.get |
Get triggers, active problems | only_true: true for currently-firing |
problem.get |
Get current problems | recent: true for unresolved |
event.get |
Get events (problems + recoveries) | Use time_from/time_to, value: 0 for recovery |
mediatype.get |
Get notification media types | selectMessageTemplates for templates |
mediatype.update |
Update webhook scripts/templates | Include full script, parameters, message_templates |
action.get |
Get trigger actions | selectOperations, selectRecoveryOperations |
action.update |
Update actions | Add recovery_operations |
trigger.update |
Rename triggers, update descriptions | Use description (name) and comments (description text) |
user.get |
Get users and their media | selectMedias for notification channels |
template.get |
Get templates and their triggers | selectTriggers |
Zabbix API Quirks (Zabbix 7.4)
- Trigger
description= trigger name (not the description text). The description text is incomments. - Status codes:
0= enabled,1= disabled for both media types and actions. templateidon host triggers: If0, the trigger was created directly on the host (not inherited from a template). Non-zero = the parent trigger ID on the template.- Severity levels:
0=Not classified,1=Information,2=Warning,3=Average,4=High,5=Disaster {EVENT.VALUE}:1= problem,0= OK/recovery{EVENT.NSEVERITY}: Numeric severity (0-5)- Webhook scripts run in Zabbix's built-in Duktape JavaScript engine (ES5 only — no
let,const, arrow functions, template literals,Array.find, etc.)
4. Host Organization & Data Model
Host Group Hierarchy
Every monitored host is assigned to multiple groups:
Host: "Kuhn's Quality Foods"
├── Clients/Kuhn's Quality Foods ← client identity
├── ISP/Zito Media, L.P. ← internet provider
└── Datto RMM Sites ← RMM platform category
This triple-grouping enables:
- Per-client dashboards — filter by
Clients/group - ISP outage detection — if 3+ hosts on same ISP go down = likely ISP issue
- RMM correlation — cross-reference Zabbix with Datto RMM agent status
Client Groups (46)
| ID | Name |
|---|---|
| 84 | Clients/3 Rivers Express |
| 90 | Clients/ABC Fire Extinguisher Inc |
| 49 | Clients/ADM Signs |
| 40 | Clients/Advanced Masonry |
| 50 | Clients/Alabek Commercial Roofing Corp. |
| 33 | Clients/All Saints Catholic Church |
| 51 | Clients/Attica Hub/Seneca Publishing |
| 42 | Clients/Bella Diamond LLC |
| 28 | Clients/Blake Dentistry |
| 85 | Clients/Bosak Eyecare & Optical |
| 55 | Clients/Bridges Health Partners Services, LLC |
| 37 | Clients/Brodaks |
| 45 | Clients/Broker's Settlement Services, Inc. |
| 43 | Clients/Brooks Diamonds |
| 57 | Clients/Buffalo Glass Block |
| 60 | Clients/CUMI America |
| 61 | Clients/Chartiers Animal Hospital Ltd |
| 58 | Clients/Cincinnati Glass Block |
| 56 | Clients/Clista Electric Inc. |
| 35 | Clients/ConnecTel, Inc. |
| 26 | Clients/Finn Chiropractic Group |
| 59 | Clients/Frew Plumbing, Heating, & Air |
| 53 | Clients/Greco Gas |
| 65 | Clients/Heart Prints Center for Early Education |
| 47 | Clients/Hergenroeder, Rega, Ewing, & Kennedy, LLC |
| 69 | Clients/Hynes Industries |
| 48 | Clients/Insurance Restoration Consultants, Inc. |
| 32 | Clients/Kuhn's Quality Foods |
| 44 | Clients/Loss Prevention Services |
| 80 | Clients/MDS Energy Development, LLC |
| 88 | Clients/Marsico Financial Group, LLC |
| 62 | Clients/Nordmann Roofing |
| 68 | Clients/North Eastern Uniforms & Equipment Inc |
| 38 | Clients/POH+W Architects |
| 75 | Clients/Penn Energy Resources |
| 86 | Clients/Pittsburgh Financial Consultants |
| 87 | Clients/Premier Automation Holdings, Inc. |
| 23 | Clients/Seubert and Associates |
| 91 | Clients/Superior Distributing Co |
| 30 | Clients/TK Plastics Company, Inc. |
| 70 | Clients/Thoroughbred Construction Group |
| 66 | Clients/Thrasher Group, Inc. |
| 71 | Clients/Universal Plastics |
| 73 | Clients/Universal Plastics Latrobe |
| 54 | Clients/V-Systems |
| 76 | Clients/Vorteq Coil Finishers |
ISP Groups (24)
| ID | Name |
|---|---|
| 25 | ISP/AT&T Enterprises, LLC |
| 27 | ISP/Armstrong |
| 24 | ISP/Bigleaf Networks, Inc. |
| 34 | ISP/Buckeye Cablevision, Inc. |
| 52 | ISP/Charter Communications Inc |
| 74 | ISP/Citizens Telecommunication Technologies, Inc |
| 67 | ISP/CityNet |
| 31 | ISP/Comcast Cable Communications, LLC |
| 46 | ISP/DQE Communications LLC |
| 63 | ISP/Expedient |
| 77 | ISP/Fidium |
| 89 | ISP/Frontier Communications of America, Inc. |
| 82 | ISP/GeoLinks |
| 78 | ISP/JACKSON ENERGY AUTHORITY |
| 39 | ISP/Level 3 Parent, LLC |
| 92 | ISP/Metalink Technologies, Inc. |
| 72 | ISP/OneCleveland |
| 64 | ISP/Space Exploration Technologies Corporation |
| 83 | ISP/UPMC |
| 79 | ISP/Ultimate Internet Access, Inc |
| 36 | ISP/Verizon Business |
| 81 | ISP/Wave Broadband |
| 41 | ISP/Windstream Communications LLC |
| 29 | ISP/Zito Media, L.P. |
Other Groups
| ID | Name | Purpose |
|---|---|---|
| 19 | Applications | Application-level monitoring |
| 20 | Databases | Database servers |
| 22 | Datto RMM Sites | Hosts also managed by Datto RMM |
| 5 | Discovered hosts | Auto-discovered hosts |
| 7 | Hypervisors | Virtualization hosts |
| 2 | Linux servers | Linux-based systems |
| 93 | Studio Imagine | Internal project |
| 6 | Virtual machines | VMs |
| 4 | Zabbix servers | Zabbix infrastructure |
Host Pattern
All client-site hosts currently use the ICMP Ping template (templateid: 10564) for basic up/down monitoring. A typical host:
Name: "Kuhn's Quality Foods"
Status: enabled
Groups: [Clients/Kuhn's Quality Foods, ISP/Zito Media L.P., Datto RMM Sites]
Templates: [ICMP Ping]
77 total hosts across the system (including Zabbix infrastructure hosts).
Global Macros
| Macro | Value |
|---|---|
{$SNMP_COMMUNITY} |
public |
5. Notification Pipeline
Current Architecture
Zabbix Trigger Fires
│
▼
Action: "Send ntfy to NOC" (actionid: 7)
├── Problem → ntfy webhook (mediatypeid: 102)
└── Recovery → ntfy webhook (same media type, different template)
│
▼
ntfy Webhook Script (Duktape JS)
├── Determines problem vs recovery (EVENT.VALUE)
├── Sets 🔴 red_circle (problem) or 🟢 green_circle (recovery)
├── Sets ntfy priority (high for problems, low for recovery)
├── Adds Click URL → Zabbix event page
├── For problems: queries Zabbix API for other active issues on same client
└── POSTs to ntfy → http://ntfy/noc-alerts
│
▼
ntfy Push Notification → user's phone
Action Configuration
Action: "Send ntfy to NOC" (actionid: 7)
- Trigger condition: Severity >= High (conditiontype 4, operator 5, value 4)
- Operations: Send message to user group "Executive" (usrgrpid: 14)
- Recovery operations: Notify all involved (operationtype: 11)
- Uses default messages (default_msg: 1) — pulls from media type templates
Users & Media
| User | Role | ntfy Media |
|---|---|---|
Lorentz Hinrichsen (lorentz@wulfconsulting.com) |
Super admin (3) | noc-alerts topic (enabled) |
Tom Carlin (tom@wulfconsulting.com) |
Super admin (3) | (removed — was duplicate to same topic) |
| Admin | Super admin (3) | (none) |
| guest | Guest (4) | (none) |
ntfy Webhook Script (Current)
The webhook script runs inside Zabbix Server's Duktape JS engine. It:
- Parses parameters from Zabbix macros
- Determines if this is a problem or recovery event
- For problems: makes 2 internal Zabbix API calls to find related active issues for the same client
- Formats and sends the ntfy notification with appropriate tags, priority, and click URL
Full script and parameters are documented in /opt/stacks/zabbix/notification-changes.md
Message Templates (Current)
| Event | ntfy Tag | Subject | Body |
|---|---|---|---|
| Problem | 🔴 red_circle |
{HOST.NAME} — {EVENT.NAME} |
Trigger description + started time + duration + related issues |
| Recovery | 🟢 green_circle |
Resolved: {HOST.NAME} — {EVENT.NAME} |
"Host is back online." + downtime + restored time |
| Update | (inherits) | Updated: {HOST.NAME} — {EVENT.NAME} |
Who updated + action + status |
Notification Example
Problem:
🔴 Kuhn's Quality Foods — Host Unreachable
Host failed to respond to 3 consecutive ICMP ping
requests. The site may be offline, the network path
disrupted, or the device powered off.
Started: 2026.03.11 at 14:22:10
Duration: 5m 30s
── Other active issues (Kuhn's Quality Foods) ──
· High Packet Loss — Kuhn's SW-Core
Recovery:
🟢 Resolved: Kuhn's Quality Foods — Host Unreachable
Host is back online.
Downtime: 22m 15s
Restored: 2026.03.11 at 14:44:25
Available but Disabled Media Types
These exist in Zabbix but are disabled. Can be enabled if needed:
- Email, Email (HTML), Gmail, Office365, SMS
- Discord, Slack, MS Teams, MS Teams Workflow, Telegram
- Jira, Jira Service Management, ServiceNow, Zendesk, PagerDuty, Opsgenie
- Many others (40+ webhook integrations available)
6. Trigger Naming Conventions
Design Principles (Established 2026-03-11)
Triggers were renamed from Zabbix defaults to be executive-friendly:
| Default Zabbix Name | Current Name | Severity |
|---|---|---|
ICMP Ping: Unavailable by ICMP ping |
Host Unreachable | High (4) |
ICMP Ping: High ICMP ping loss |
High Packet Loss | Warning (2) |
ICMP Ping: High ICMP ping response time |
Slow Response Time | Warning (2) |
Naming Rules
- No technical jargon in trigger names — use impact-based language
- Trigger descriptions (comments field) contain the technical detail: what the check does, thresholds, possible causes
- Keep names short — they appear in ntfy subjects, Teams cards, dashboards
- No host name in trigger name —
{HOST.NAME}is added by the notification template
Cisco Triggers (Not Yet Renamed)
The Cisco Catalyst SNMP templates have their own ICMP triggers that still use the old naming:
Cisco Catalyst 3750V2-24FS: Unavailable by ICMP pingCisco Catalyst 3750V2-24FS: High ICMP ping loss- etc.
These are on separate templates (not the "ICMP Ping" template) and have templateid: 0 on host triggers. Renaming these requires updating each Cisco template individually.
7. Grafana Integration
Plugin
- alexanderzobnin-zabbix-app v6.2.1 — connects directly to Zabbix API
- Datasource URL (internal):
http://zabbix-frontend:8080/api_jsonrpc.php
Planned: MSP Executive Status Board
Design goal: at-a-glance dashboard for management showing:
| Panel | Type | Data Source |
|---|---|---|
| Current problems by severity | Stat panels | Zabbix problems |
| Problems per client | Bar gauge | Zabbix trigger groups |
| Active problem list | Table | Zabbix problems |
| SLA/uptime per client | Zabbix SLA panel | Zabbix SLA |
| Host status grid | Status map plugin | Zabbix hosts |
Filter by Clients/ host groups. Use Grafana variables for client selection dropdown.
8. Pulse Integration Architecture
Overview
Pulse is the internal Node.js/TypeScript web app with API access to:
- Zabbix (this system)
- PSA (ticketing)
- Datto RMM
- Veeam (backups)
- Microsoft Graph (Teams, email)
- Zoom
- Apprise (notification routing)
Planned: Morning NOC Summary
Full architecture document: /opt/stacks/zabbix/pulse-morning-summary-architecture.md
Key points:
- Scheduled job at 6:30 AM weekdays
- Aggregates data from Zabbix + PSA + Veeam in parallel
- Sends Teams adaptive card (direct via MS Graph), email/ntfy (via Apprise)
- User-configurable delivery preferences
- Killer feature: unmatched alerts — Zabbix problems with no PSA ticket
Zabbix API Queries for Pulse
Get all open problems with host/client context:
// 1. Get open problems
const problems = await zabbixApi('problem.get', {
recent: true,
sortfield: ['eventid'],
sortorder: 'DESC'
});
// 2. Get host → client mapping (cache this)
const hosts = await zabbixApi('host.get', {
output: ['hostid', 'host', 'name'],
selectHostGroups: ['groupid', 'name']
});
// 3. Build client map
const clientMap = {};
for (const host of hosts) {
const clientGroup = host.hostgroups.find(g => g.name.startsWith('Clients/'));
if (clientGroup) {
clientMap[host.hostid] = clientGroup.name.replace('Clients/', '');
}
}
Get overnight resolved events:
const resolved = await zabbixApi('event.get', {
source: 0,
object: 0,
value: 0, // recovery events only
time_from: Math.floor(yesterday6pm.getTime() / 1000),
time_to: Math.floor(today630am.getTime() / 1000),
selectHosts: ['name'],
selectRelatedObject: ['description'],
sortfield: ['clock'],
sortorder: 'DESC'
});
9. Development Patterns & Gotchas
Zabbix Webhook Script Constraints
The webhook script runs in Duktape (ES5 JavaScript engine):
DO:
var x = 'hello'; // var only
for (var i = 0; i < arr.length; i++) { } // classic for loops
JSON.parse(), JSON.stringify() // available
new HttpRequest() // Zabbix's HTTP client
btoa() // Base64 encoding available
DON'T:
let x = 'hello'; // NO let/const
const y = () => {}; // NO arrow functions
`template ${literal}`; // NO template literals
arr.find(x => x.id === 1); // NO Array.find/includes/map
for (const x of arr) {} // NO for...of
HttpRequest in Webhooks
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
req.addHeader('Authorization: Bearer TOKEN');
var resp = req.post(url, body); // POST
var resp = req.put(url, body); // PUT
var resp = req.get(url); // GET
var status = req.getStatus(); // HTTP status code
Multiple HttpRequest instances CAN be created in the same script (used for the related-problems enrichment that calls Zabbix API before calling ntfy).
API Update Patterns
When updating a media type, you must include the FULL array for parameters and message_templates — they're replaced entirely, not merged.
# WRONG — this deletes all other parameters
mediatype.update({ parameters: [{"name": "new_param", "value": "x"}] })
# RIGHT — include ALL parameters
mediatype.update({ parameters: [
{"name": "endpoint", "value": "http://ntfy/noc-alerts"},
{"name": "username", "value": "monitoring"},
# ... all existing params ...
{"name": "new_param", "value": "x"}
] })
Trigger Description vs Comments
This is confusing in the Zabbix API:
descriptionfield = the trigger name (what you see in the UI)commentsfield = the description text (the explanation paragraph)
{
"triggerid": "23176",
"description": "Host Unreachable", // ← this is the NAME
"comments": "Host failed to respond to..." // ← this is the DESCRIPTION
}
Host Group Filtering Pattern
To get the client name for a host:
// Get host groups
var groups = hostData.hostgroups;
var clientName = null;
for (var i = 0; i < groups.length; i++) {
if (groups[i].name.indexOf("Clients/") === 0) {
clientName = groups[i].name.replace("Clients/", "");
break;
}
}
// clientName = "Kuhn's Quality Foods"
Docker Exec for API Calls
Since the Zabbix frontend doesn't have ports mapped to the host, API calls from the host must go through docker exec:
docker exec zabbix-frontend curl -s -X POST \
"http://localhost:8080/api_jsonrpc.php" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{"jsonrpc":"2.0","method":"...","params":{...},"id":1}'
Or use Python for complex payloads (escaping JSON in bash is fragile):
import json, subprocess
payload = json.dumps({...})
result = subprocess.run(
["docker", "exec", "zabbix-frontend", "curl", "-s", "-X", "POST",
"http://localhost:8080/api_jsonrpc.php",
"-H", "Content-Type: application/json",
"-H", f"Authorization: Bearer {TOKEN}",
"-d", payload],
capture_output=True, text=True
)
data = json.loads(result.stdout)
External API Access (from Pulse or other servers)
const response = await fetch('https://zabbix.wulfconsulting.cloud/api_jsonrpc.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ZABBIX_API_TOKEN}`
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'problem.get',
params: { recent: true },
id: 1
})
});
10. API Cookbook
Get All Active Problems
{
"method": "problem.get",
"params": {
"output": "extend",
"recent": true,
"sortfield": ["eventid"],
"sortorder": "DESC"
}
}
Get Active Problems for a Specific Client
{
"method": "trigger.get",
"params": {
"output": ["triggerid", "description", "lastchange", "priority"],
"groupids": ["32"],
"only_true": true,
"selectHosts": ["name"],
"skipDependent": true
}
}
(groupid 32 = Clients/Kuhn's Quality Foods)
Get All Hosts with Client + ISP Mapping
{
"method": "host.get",
"params": {
"output": ["hostid", "host", "name", "status"],
"selectHostGroups": ["groupid", "name"],
"selectParentTemplates": ["templateid", "name"]
}
}
Get Recovery Events in a Time Window
{
"method": "event.get",
"params": {
"source": 0,
"object": 0,
"value": 0,
"time_from": 1741647600,
"time_to": 1741692600,
"selectHosts": ["name"],
"selectRelatedObject": ["description"],
"sortfield": ["clock"],
"sortorder": "DESC"
}
}
Update a Trigger Name + Description
{
"method": "trigger.update",
"params": {
"triggerid": "23176",
"description": "Host Unreachable",
"comments": "Host failed to respond to 3 consecutive ICMP ping requests."
}
}
Get Media Type with Full Details
{
"method": "mediatype.get",
"params": {
"output": "extend",
"selectMessageTemplates": "extend",
"mediatypeids": ["102"]
}
}
Test ntfy Notification Manually
docker exec zabbix-frontend curl -s -X PUT \
-H "Authorization: Basic $(echo -n 'monitoring:GBigt1231#' | base64)" \
-H "Title: Test Notification" \
-H "Priority: 3" \
-H "Tags: red_circle" \
"http://ntfy/noc-alerts" \
-d "This is a test notification from Zabbix"
Related Documentation
- Notification changes (before/after + restoration):
/opt/stacks/zabbix/notification-changes.md - Pulse morning summary architecture:
/opt/stacks/zabbix/pulse-morning-summary-architecture.md - Docker Compose:
/opt/stacks/zabbix/compose.yml - Zabbix SSO setup:
/opt/stacks/zabbix/ENTRA-AUTHENTIK-ZABBIX-SSO.md - Zabbix 7.4 API docs: https://www.zabbix.com/documentation/7.4/en/manual/api