{
  "name": "Monitor scraper and endpoint health with Datasource Pulse and Slack alerts",
  "nodes": [
    {
      "parameters": {
        "content": "## Monitor scraper and endpoint health with Datasource Pulse and Slack alerts\n\n**Who's it for**\nTeams running Apify scrapers that feed dashboards, pipelines, or customer-facing features, and anyone with an endpoint that must stay up.\n\n**How it works**\nEvery 6 hours this workflow runs Datasource Pulse (an Apify Actor) over two checks: your scraper's recent runs, and the endpoint it feeds. Each check returns one verdict with a stable failure_class. Anything not healthy becomes a Slack message with what broke, the failure class, and the downstream impact note you wrote into the check.\n\n**How to set up (5 min)**\n1. Install the **Apify** community node (n8n Cloud: search \"Apify\" in the nodes panel and install) and connect your Apify account.\n2. Open **Initiate Datasource Pulse** and edit *Input JSON*:\n   - `actorId`: your scraper, e.g. `username~my-scraper`\n   - `apifyToken`: token with Actor read + run-read scope\n   - `url`: the endpoint your scraper feeds\n3. Pick your channel in **Send Slack Alert**.\n4. Run once and confirm the alert fires. The IF node ships preset to pass anything whose state is not healthy.\n\n**Requirements**\nApify account (free tier works, checks cost $0.02 each), the Apify community node (verified on n8n Cloud; self-hosted installs @apify/n8n-nodes-apify), a Slack connection.\n\n**How to customize**\nSwap the actorId, point the HTTP check at any endpoint, adjust the schedule. Datasource Pulse also validates API keys for 35+ pre-wired vendors, a head start, not a limit: anything else with an HTTP endpoint fits a generic_http check. Cost: $0.02 per check per run; 2 checks at 4 runs/day is about $4.90/month.\n\nDocs: https://datasourcepulse.com/integrations/n8n",
        "width": 520,
        "height": 1200
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -688,
        -144
      ],
      "id": "397bdbce-c146-4ecf-9cf4-efda8a604484",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Scheduled health check\n\nStarts the workflow every six hours and runs the Datasource Pulse check through Apify to monitor scraper and endpoint health.",
        "width": 432,
        "height": 320,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -128,
        -112
      ],
      "id": "57797239-24a9-47bc-a03f-a9c04fb60163",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## Evaluate and alert\n\nChecks whether the Datasource Pulse result indicates an unhealthy source and sends a Slack notification when attention is needed.",
        "width": 432,
        "height": 336,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        352,
        -144
      ],
      "id": "0096cf2d-f084-4513-a7e9-21e80dc87355",
      "name": "Sticky Note2"
    },
    {
      "id": "schedule-trigger",
      "name": "When Every 6 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -80,
        40
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "run-datasource-pulse",
      "name": "Initiate Datasource Pulse",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        160,
        40
      ],
      "parameters": {
        "actorId": {
          "__rl": true,
          "mode": "list",
          "value": "UEt39k7v1DkIYp8Gh",
          "cachedResultUrl": "https://console.apify.com/actors/UEt39k7v1DkIYp8Gh/input",
          "cachedResultName": "Datasource Pulse (growth_wizard/datasource-pulse)"
        },
        "resource": "Actors",
        "operation": "Run actor and get dataset",
        "customBody": "{\n  \"checks\": [\n    {\n      \"type\": \"actor\",\n      \"id\": \"my-scraper\",\n      \"label\": \"My scraper · runs green\",\n      \"actorId\": \"username~my-scraper\",\n      \"apifyToken\": \"PASTE_APIFY_TOKEN_WITH_ACTOR_READ_AND_RUN_READ_SCOPE\",\n      \"enableVolumeBaseline\": false,\n      \"enableCostBaseline\": false,\n      \"impact\": \"Downstream dashboards go stale when this scraper fails\"\n    },\n    {\n      \"type\": \"credential\",\n      \"id\": \"feed-endpoint\",\n      \"label\": \"Data endpoint · reachable\",\n      \"vendor\": \"generic_http\",\n      \"url\": \"https://example.com/api/data\",\n      \"successStatusCode\": 200,\n      \"impact\": \"Consumers read from this endpoint\"\n    }\n  ]\n}",
        "actorSource": "recentlyUsed"
      },
      "typeVersion": 1
    },
    {
      "id": "if-unhealthy",
      "name": "If State Unhealthy",
      "type": "n8n-nodes-base.if",
      "position": [
        400,
        40
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "state-not-healthy",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.state }}",
              "rightValue": "healthy"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "slack-alert",
      "name": "Send Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        640,
        20
      ],
      "parameters": {
        "text": "=🚨 *Datasource Pulse* · {{ $json.connector_label }}\nState: *{{ $json.state }}*{{ $json.failure_class ? ' · ' + $json.failure_class : '' }}\n{{ $json.message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "alerts"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.2
    }
  ],
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "If State Unhealthy": {
      "main": [
        [
          {
            "node": "Send Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Every 6 Hours": {
      "main": [
        [
          {
            "node": "Initiate Datasource Pulse",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initiate Datasource Pulse": {
      "main": [
        [
          {
            "node": "If State Unhealthy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
