{
  "name": "API Health Check",
  "description": "Pings a URL every 15 minutes and notifies you, plus logs the timestamp, whenever it returns a non-200 status — an integration-free uptime check.",
  "tags": [
    "uptime",
    "monitor",
    "health check",
    "schedule",
    "alert",
    "api"
  ],
  "type": "triggered",
  "nodes": [
    {
      "id": "sticky-intro",
      "position": {
        "x": 20,
        "y": 20
      },
      "data": {
        "color": "#fff266",
        "content": "🩺 Keep an eye on an endpoint.\n\nEvery 15 minutes this sends a request to a URL and reads the HTTP status. If it's anything other than 200 OK, you get a notification and the failure time is written to the Data Store. Set your endpoint in 'Ping the endpoint' and keep the browser open.",
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "type": "stickyNote",
      "width": 360,
      "height": 200,
      "measured": {
        "width": 360,
        "height": 200
      }
    },
    {
      "id": "trigger-schedule",
      "position": {
        "x": 120,
        "y": 320
      },
      "data": {
        "instance": {
          "id": "af-base-node:trigger:schedule"
        },
        "label": "Every 15 minutes",
        "inputs": {
          "rules": [
            {
              "triggerInterval": "minutes",
              "minutesBetweenTriggers": 15
            }
          ]
        },
        "parameters": {
          "notes": "Runs every 15 minutes while the browser is open."
        },
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "type": "trigger",
      "measured": {
        "width": 50,
        "height": 50
      }
    },
    {
      "id": "ping",
      "position": {
        "x": 440,
        "y": 320
      },
      "data": {
        "instance": {
          "id": "af-base-node:basic:httpRequest"
        },
        "label": "Ping the endpoint",
        "inputs": {
          "method": "GET",
          "url": "https://api.awflow.io",
          "options": {
            "response": {
              "includeResponseHeaderAndStatus": true
            }
          }
        },
        "parameters": {
          "notes": "Requests your URL and, because status is included, exposes the HTTP status code for the check below. Swap in your real endpoint."
        },
        "runned": false,
        "isRunning": false,
        "failed": false,
        "wasRunned": false,
        "skipped": false
      },
      "type": "basic",
      "measured": {
        "width": 50,
        "height": 50
      },
      "selected": false
    },
    {
      "id": "is-down",
      "position": {
        "x": 760,
        "y": 320
      },
      "data": {
        "instance": {
          "id": "af-base-node:if:if"
        },
        "label": "Is it unhealthy?",
        "inputs": {
          "conditions": [
            {
              "leftSide": "{{ $input.status }}",
              "rightSide": 200,
              "operator": {
                "operationType": "number",
                "operatorValue": "!="
              }
            }
          ]
        },
        "parameters": {
          "notes": "True (top port) fires when the status is not 200. The healthy path (200) simply ends the run with no alert."
        },
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "type": "if",
      "measured": {
        "width": 50,
        "height": 50
      },
      "selected": false
    },
    {
      "id": "notify",
      "position": {
        "x": 1080,
        "y": 220
      },
      "data": {
        "instance": {
          "id": "af-base-node:basic:showNotificationNode"
        },
        "label": "Show the alert",
        "inputs": {
          "title": "Endpoint health check failed",
          "message": "{{ $('Ping the endpoint').url }} returned status {{ $('Ping the endpoint').status }}.",
          "options": {
            "priority": "high",
            "requireInteraction": true
          }
        },
        "parameters": {
          "notes": "Pops a high-priority notification with the failing URL and status. Only runs when the status is not 200."
        },
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "type": "basic",
      "measured": {
        "width": 50,
        "height": 50
      },
      "selected": false
    },
    {
      "id": "get-now",
      "position": {
        "x": 1400,
        "y": 220
      },
      "data": {
        "instance": {
          "id": "af-base-node:basic:getCurrentDate"
        },
        "label": "Timestamp the failure",
        "inputs": {
          "outputFieldName": "ts"
        },
        "parameters": {
          "notes": "Captures the current date/time so we can record exactly when the failure was seen."
        },
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "type": "basic",
      "measured": {
        "width": 50,
        "height": 50
      }
    },
    {
      "id": "log-fail",
      "position": {
        "x": 1720,
        "y": 220
      },
      "data": {
        "instance": {
          "id": "af-base-node:basic:dataStore"
        },
        "label": "Log the failure time",
        "inputs": {
          "operation": "set",
          "scope": "workflow",
          "key": "last-failure",
          "value": "{{ $input.ts }}",
          "valueFormat": "text"
        },
        "parameters": {
          "notes": "Writes the failure timestamp to the Data Store so you have a record of the last outage."
        },
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "type": "basic",
      "measured": {
        "width": 50,
        "height": 50
      },
      "selected": false
    },
    {
      "id": "617def25-32f0-40cd-8a21-a1924ac51ab9",
      "type": "basic",
      "position": {
        "x": 1110,
        "y": 435
      },
      "data": {
        "instance": {
          "id": "af-base-node:basic:showNotificationNode"
        },
        "label": "showNotificationNode-8-771",
        "inputs": {
          "title": "Endpoint health check was successful",
          "message": "{{ $('Ping the endpoint').url }} returned status {{ $('Ping the endpoint').status }}.",
          "options": {
            "priority": "high",
            "requireInteraction": true
          }
        },
        "parameters": {
          "notes": "Pops a high-priority notification with the succesful URL and status. Only runs when the status is 200."
        },
        "runned": false,
        "wasRunned": false,
        "failed": false,
        "isRunning": false,
        "skipped": false
      },
      "origin": [
        0.5,
        0
      ],
      "measured": {
        "width": 50,
        "height": 50
      },
      "selected": true,
      "dragging": false
    }
  ],
  "edges": [
    {
      "id": "e-schedule-ping",
      "type": "flowEdge",
      "source": "trigger-schedule",
      "target": "ping",
      "markerEnd": {
        "type": "arrowclosed"
      }
    },
    {
      "id": "e-ping-if",
      "type": "flowEdge",
      "source": "ping",
      "target": "is-down",
      "markerEnd": {
        "type": "arrowclosed"
      }
    },
    {
      "id": "e-if-notify",
      "type": "flowEdge",
      "source": "is-down",
      "target": "notify",
      "sourceHandle": "output-0",
      "markerEnd": {
        "type": "arrowclosed"
      }
    },
    {
      "id": "e-notify-now",
      "type": "flowEdge",
      "source": "notify",
      "target": "get-now",
      "markerEnd": {
        "type": "arrowclosed"
      }
    },
    {
      "id": "e-now-log",
      "type": "flowEdge",
      "source": "get-now",
      "target": "log-fail",
      "markerEnd": {
        "type": "arrowclosed"
      }
    },
    {
      "source": "is-down",
      "sourceHandle": "output-1",
      "target": "617def25-32f0-40cd-8a21-a1924ac51ab9",
      "targetHandle": "input-0",
      "id": "xy-edge__is-downoutput-1-617def25-32f0-40cd-8a21-a1924ac51ab9input-0",
      "markerEnd": {
        "type": "arrowclosed"
      }
    }
  ]
}