> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkmk Webhook Setup Guide

> Configure Checkmk to deliver events to StackOne.

## Prerequisites

The connector should already be set up, with a Connector Profile and a Linked Account. See [Getting Started](/connectors/checkmk#getting-started) on the Checkmk connector page.

<section data-guide-section data-guide-scopes="">
  <h2>Install the StackOne notification script</h2>

  <p>Checkmk has no generic outbound webhook. Events are delivered by a small notification script that you install once on your Checkmk server. Checkmk runs it for every matching notification, and the script forwards the notification to StackOne as JSON. See the <a href="https://docs.checkmk.com/latest/en/notifications.html" target="_blank" rel="noopener noreferrer">Checkmk notifications documentation</a> for background.</p>

  <Steps>
    <Step title="Retrieve StackOne Native Webhook URL">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>The <strong>Native Webhook URL</strong> is generated once an account has been linked. You pass it to the script as its only parameter in a later step.</p>

        <ul>
          <li>Open the linked account in StackOne.</li>
          <li>Copy the value from <strong>Native Webhook URL</strong>.</li>
          <li>The URL contains a secret token that authenticates deliveries, so store it securely and do not share it.</li>
        </ul>
      </div>
    </Step>

    <Step title="Install the script on your Checkmk server">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Save the script below on the Checkmk server as `/omd/sites/<site-id>/local/share/check_mk/notifications/stackone_webhook`, where `<site-id>` is your Checkmk site name (for example `mysite`). Run the commands as the site user, for example after `omd su <site-id>`. The script uses only the Python 3 standard library that ships with Checkmk and needs no extra packages.</p>

        ```python theme={null}
        #!/usr/bin/env python3
        # StackOne Webhook
        # Forwards Checkmk notifications to StackOne as JSON.
        # Parameter 1 (required) = StackOne Native Webhook URL
        import json, os, sys, urllib.error, urllib.request
        from datetime import datetime, timezone

        TYPES = {
            "ACKNOWLEDGEMENT": "acknowledged",
            "FLAPPINGSTART": "flapping_started",
            "FLAPPINGSTOP": "flapping_stopped",
            "DOWNTIMESTART": "downtime_started",
            "DOWNTIMEEND": "downtime_ended",
            "DOWNTIMECANCELLED": "downtime_cancelled",
        }
        HOST_PROBLEMS = {"DOWN": "host_down", "UNREACHABLE": "host_unreachable"}
        SERVICE_PROBLEMS = {"WARN": "service_warning", "WARNING": "service_warning",
                            "CRIT": "service_critical", "CRITICAL": "service_critical",
                            "UNKNOWN": "service_unknown"}


        def classify(ntype, what, hs, ss):
            scope = "service" if what == "SERVICE" else "host"
            if ntype == "CUSTOM":
                return "verification"
            if ntype == "PROBLEM":
                problems = SERVICE_PROBLEMS if scope == "service" else HOST_PROBLEMS
                return problems.get(ss if scope == "service" else hs, "unmapped")
            if ntype == "RECOVERY":
                return "service_ok" if scope == "service" else "host_up"
            if ntype in TYPES:
                return "%s_%s" % (scope, TYPES[ntype])
            return "unmapped"


        def main():
            e = {k[7:]: v for k, v in os.environ.items() if k.startswith("NOTIFY_")}
            url = e.get("PARAMETER_1")
            if not url:
                sys.stderr.write("stackone_webhook: missing webhook URL parameter\n")
                return 2
            ntype, what = e.get("NOTIFICATIONTYPE", ""), e.get("WHAT", "")
            hs, ss = e.get("HOSTSTATE", ""), e.get("SERVICESTATE", "")
            event = classify(ntype, what, hs, ss)
            micro = e.get("MICROTIME")
            if micro:
                ts = datetime.fromtimestamp(int(micro) / 1e6, tz=timezone.utc).isoformat()
            else:
                ts = datetime.now(timezone.utc).isoformat()
            service = e.get("SERVICEDESC") if what == "SERVICE" else None
            subject = e.get("HOSTNAME", "unknown") + (":" + service if service else "")
            body = {
                "event": event,
                "event_id": "%s-%s-%s" % (subject, ntype, micro or ts),
                "event_date": ts,
                "notification_type": ntype,
                "what": what,
                "host_name": e.get("HOSTNAME"),
                "host_address": e.get("HOSTADDRESS"),
                "host_state": hs or None,
                "previous_host_state": e.get("LASTHOSTSTATE") or None,
                "host_output": e.get("HOSTOUTPUT"),
                "service_description": service,
                "service_state": (ss or None) if service else None,
                "previous_service_state": (e.get("LASTSERVICESTATE") or None) if service else None,
                "service_output": e.get("SERVICEOUTPUT") if service else None,
                "contact_name": e.get("CONTACTNAME"),
                "omd_site": e.get("OMD_SITE"),
                "long_date_time": e.get("LONGDATETIME"),
            }
            req = urllib.request.Request(url, data=json.dumps(body).encode(),
                                         headers={"Content-Type": "application/json",
                                                  "User-Agent": "stackone-checkmk-webhook/2.0",
                                                  "Accept": "application/json"})
            try:
                urllib.request.urlopen(req, timeout=10)
            except urllib.error.HTTPError as err:
                if event == "unmapped" and err.code == 400:
                    return 0  # StackOne deliberately does not route unmapped notification types
                raise
            return 0


        if __name__ == "__main__":
            sys.exit(main())
        ```

        <ul>
          <li>Make the script executable with `chmod +x /omd/sites/<site-id>/local/share/check_mk/notifications/stackone_webhook`.</li>
          <li>The script appears as <strong>StackOne Webhook</strong> in the notification method list.</li>
        </ul>
      </div>
    </Step>
  </Steps>
</section>

<section data-guide-section data-guide-scopes="">
  <h2>Create the notification rule</h2>

  <p>Wire the installed script into a notification rule so Checkmk invokes it for the events you want delivered to StackOne. Notification rules take effect immediately without "Activate changes".</p>

  <Steps>
    <Step title="Open the Notifications page">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>In the Checkmk navigation bar, open <strong>Setup</strong> and click <strong>Notifications</strong> in the <strong>Events</strong> section.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-open-notifications.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=21c1351957476c965c88d575275f24f5" alt="Checkmk Setup menu with Notifications highlighted in the Events section" width="1280" height="800" data-path="connectors/checkmk/images/events-open-notifications.png" />
      </div>
    </Step>

    <Step title="Add a notification rule">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>On the <strong>Notifications</strong> page, click <strong>Add notification rule</strong>.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-add-notification-rule.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=904c35fc6500ccdaa5822e31bd232dad" alt="Notifications page with the Add notification rule button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-add-notification-rule.png" />
      </div>
    </Step>

    <Step title="Choose the triggering events">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>In <strong>Triggering events</strong>, select <strong>All events</strong> so every host and service notification is forwarded, or keep <strong>Specific events</strong> and pick only the host and service state changes you need. Click <strong>Next step: Specify host/services</strong>, optionally narrow the rule in <strong>Filter for hosts/services</strong>, then continue to <strong>Notification method (plug-in)</strong>.</p>

        <ul>
          <li>Checkmk's factory <strong>Notified events for hosts</strong> rule excludes the unreachable state, so <strong>Host Unreachable</strong> (`host_unreachable`) events never fire out of the box. To receive them, edit that rule under <strong>Supporting rules</strong> on the <strong>Notifications</strong> page and include unreachable events.</li>
        </ul>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-triggering-events.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=2b7ad73b540e6af1174fc57ef6348798" alt="Triggering events stage with the All events toggle and the Next step button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-triggering-events.png" />
      </div>
    </Step>

    <Step title="Select the StackOne notification method">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>In <strong>Notification method (plug-in)</strong>, keep <strong>Send notification</strong>, open the method dropdown and select <strong>StackOne Webhook</strong>.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-notification-method.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=693018256bcce75ce9d3dd8b56feb352" alt="Method dropdown open with the StackOne Webhook option highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-notification-method.png" />
      </div>
    </Step>

    <Step title="Create the parameter set">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Next to <strong>Select parameters</strong>, click <strong>Create</strong> to add a parameter set for the method.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-create-parameters.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=fd681c77a23ac6548820503e96ffd414" alt="Select parameters row with the Create button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-create-parameters.png" />
      </div>
    </Step>

    <Step title="Enter the Native Webhook URL">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>In <strong>New StackOne Webhook parameter</strong>, enter a <strong>Description</strong> such as `StackOne webhook`. Under <strong>Parameters</strong>, paste the <strong>Native Webhook URL</strong> from the linked account into the first field of <strong>Call with the following parameters</strong>, then click <strong>Save</strong>. The new parameter set is selected automatically.</p>

        <ul>
          <li>Parameter sets can be edited later from the <strong>Notifications</strong> page via <strong>Parameters for notification methods</strong>.</li>
        </ul>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-parameters.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=ae584b6eec4d57a646e356d2d90dc4fe" alt="New StackOne Webhook parameter form with the Description field, the first parameter field and the Save button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-parameters.png" />
      </div>
    </Step>

    <Step title="Set a single recipient">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>In <strong>Recipient</strong>, change <strong>Select recipient</strong> to <strong>Specific users</strong> and pick one user who can see all hosts and services. Checkmk runs the script once per recipient, so a single user sends each event to StackOne exactly once. The recipient does not change where events are delivered.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-recipient.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=9b4061af0ab4e632004b49fa929f154b" alt="Recipient stage with Specific users and the selected user highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-recipient.png" />
      </div>
    </Step>

    <Step title="Name the rule">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Skip <strong>Sending conditions</strong>. In <strong>General properties</strong>, enter a <strong>Description</strong> such as `StackOne webhook` and click <strong>Next step: Review all settings</strong>.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-general-properties.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=ac189d6908f77dff301b22ec9a68840b" alt="General properties stage with the Description field and the review button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-general-properties.png" />
      </div>
    </Step>

    <Step title="Save the rule">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Review the summary and click <strong>Apply & test notification rule</strong>. Checkmk saves the rule and opens <strong>Test notifications</strong>.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-save-rule.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=e2113b9f771453baafadb2537024a27c" alt="Rule summary with the Apply and test notification rule button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-save-rule.png" />
      </div>
    </Step>
  </Steps>
</section>

<section data-guide-section data-guide-scopes="">
  <h2>Verify the connection</h2>

  <p>Confirm that the script and rule deliver events to StackOne. Either check below works; the custom notification is the only one that produces the <strong>Webhook Verification</strong> event.</p>

  <Steps>
    <Step title="Send a test notification">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>On <strong>Test notifications</strong>, choose a <strong>Host</strong>, tick <strong>Trigger notification for a specific method</strong>, select <strong>StackOne Webhook</strong> and your parameter set under <strong>Notification method and parameter</strong>, then click <strong>Test notifications</strong>.</p>

        <ul>
          <li>Without <strong>Trigger notification for a specific method</strong>, Checkmk only analyzes which rules would match and sends nothing.</li>
          <li>The test simulates a real state change (by default <strong>UP</strong> to <strong>DOWN</strong>), so StackOne receives it as a <strong>Host Down</strong> (`host_down`) event.</li>
        </ul>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-test-notifications.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=7b6fbd6a55f155bfdba29ba784acaa62" alt="Test notifications page with the Host, Trigger notification for a specific method, method and Test notifications controls highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-test-notifications.png" />
      </div>
    </Step>

    <Step title="Send a custom notification">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Open a monitored host in <strong>Monitor</strong>, open the <strong>Commands</strong> menu and choose <strong>Send custom notification</strong> (click the show-more icon in the menu if it is not listed).</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-custom-notification-command.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=a4e9cb70d056c2b5f96dd8b7923a52ef" alt="Host status page with the Commands menu open and Send custom notification highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-custom-notification-command.png" />
      </div>
    </Step>

    <Step title="Send the verification event">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Enter a <strong>Comment</strong> and click <strong>Send</strong>, then confirm with <strong>Send</strong>. StackOne receives the notification as a <strong>Webhook Verification</strong> (`verification`) event.</p>

        <img src="https://mintcdn.com/stackone-60/03bB1klfBCOVqNCb/connectors/checkmk/images/events-send-custom-notification.png?fit=max&auto=format&n=03bB1klfBCOVqNCb&q=85&s=0d31d31f2940268314c39169465c9fb2" alt="Send custom notification form with the Comment field and the Send button highlighted" width="1280" height="800" data-path="connectors/checkmk/images/events-send-custom-notification.png" />
      </div>
    </Step>
  </Steps>
</section>

<section data-guide-section data-guide-scopes="">
  <h2>Available webhook events</h2>

  <p>The StackOne notification script maps Checkmk notifications to the events below. Which notifications are sent is controlled by the rule's <strong>Triggering events</strong>, and only events selected in StackOne are delivered to you.</p>

  <Steps>
    <Step title="Verification event">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Fired by a Checkmk custom notification rather than a real state change.</p>

        <ul>
          <li><strong>Webhook Verification</strong> (`verification`) — Fired when an admin sends a Checkmk custom notification; used to confirm the webhook is wired correctly</li>
        </ul>
      </div>
    </Step>

    <Step title="Host events">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Events related to the state of monitored hosts.</p>

        <ul>
          <li><strong>Host Down</strong> (`host_down`) — Fired when a monitored host changes to the DOWN state</li>
          <li><strong>Host Unreachable</strong> (`host_unreachable`) — Fired when a host becomes UNREACHABLE, typically because its parent host is down</li>
          <li><strong>Host Up</strong> (`host_up`) — Fired when a monitored host recovers to the UP state</li>
          <li><strong>Host Problem Acknowledged</strong> (`host_acknowledged`) — Fired when a contact acknowledges a host problem</li>
          <li><strong>Host Flapping Started</strong> (`host_flapping_started`) — Fired when a host starts flapping between states</li>
          <li><strong>Host Flapping Stopped</strong> (`host_flapping_stopped`) — Fired when a host stops flapping between states</li>
          <li><strong>Host Downtime Started</strong> (`host_downtime_started`) — Fired when a scheduled downtime begins for a host</li>
          <li><strong>Host Downtime Ended</strong> (`host_downtime_ended`) — Fired when a scheduled host downtime ends at its planned end time</li>
          <li><strong>Host Downtime Canceled</strong> (`host_downtime_cancelled`) — Fired when a scheduled host downtime is removed before its planned end time</li>
        </ul>
      </div>
    </Step>

    <Step title="Service events">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Events related to the state of monitored services.</p>

        <ul>
          <li><strong>Service Warning</strong> (`service_warning`) — Fired when a service enters the WARNING state</li>
          <li><strong>Service Critical</strong> (`service_critical`) — Fired when a service enters the CRITICAL state</li>
          <li><strong>Service Unknown</strong> (`service_unknown`) — Fired when a service enters the UNKNOWN state</li>
          <li><strong>Service Recovered</strong> (`service_ok`) — Fired when a service recovers to the OK state</li>
          <li><strong>Service Problem Acknowledged</strong> (`service_acknowledged`) — Fired when a contact acknowledges a service problem</li>
          <li><strong>Service Flapping Started</strong> (`service_flapping_started`) — Fired when a service starts flapping between states</li>
          <li><strong>Service Flapping Stopped</strong> (`service_flapping_stopped`) — Fired when a service stops flapping between states</li>
          <li><strong>Service Downtime Started</strong> (`service_downtime_started`) — Fired when a scheduled downtime begins for a service</li>
          <li><strong>Service Downtime Ended</strong> (`service_downtime_ended`) — Fired when a scheduled service downtime ends at its planned end time</li>
          <li><strong>Service Downtime Canceled</strong> (`service_downtime_cancelled`) — Fired when a scheduled service downtime is removed before its planned end time</li>
        </ul>
      </div>
    </Step>
  </Steps>
</section>

<section data-guide-section data-guide-scopes="">
  <h2>Delivery format</h2>

  <p>Details of how the StackOne notification script delivers events.</p>

  <Steps>
    <Step title="One JSON request per notification">
      <div data-guide-step data-guide-scopes="" data-guide-display-scopes-list="">
        <p>Each Checkmk notification produces a single HTTPS POST with a flat JSON body; there is no batching. The `event` field identifies the event, `event_id` and `event_date` are generated by the script, and host or service fields that do not apply to an event are null. Notification types without a matching event (such as alert handler notifications) are sent with `event` set to `unmapped` and are not processed by StackOne. Requests are not signed; delivery security relies on the secret embedded in the Native Webhook URL.</p>
      </div>
    </Step>
  </Steps>
</section>

## Verify

Your Connector should now be able to receive and process events. Try triggering an event and you should see an Event appear in the Connector logs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.