AutomationFlowsData & Sheets › Ssl Certificate Expiry Notifier (no Paid Apis)

Ssl Certificate Expiry Notifier (no Paid Apis)

ByEvoort Solutions @evoortsolutions on n8n.io

Great — here’s a complete Workflow Description for your n8n Creator submission based on the JSON you shared:

Cron / scheduled trigger★★★★☆ complexity13 nodesGoogle SheetsHTTP RequestEmail Send
Data & Sheets Trigger: Cron / scheduled Nodes: 13 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #4643 — we link there as the canonical source.

This workflow follows the Emailsend → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "NTSkPEG2pcvG3qoH",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "SSL Expiry Notifier",
  "tags": [
    {
      "id": "b2GfRjIENZV9WKpD",
      "name": "IT Ops",
      "createdAt": "2025-05-29T08:33:47.664Z",
      "updatedAt": "2025-05-29T08:33:47.664Z"
    },
    {
      "id": "sfoRiNMRAXjQ31IO",
      "name": "DevOps",
      "createdAt": "2025-05-29T08:33:47.654Z",
      "updatedAt": "2025-05-29T08:33:47.654Z"
    }
  ],
  "nodes": [
    {
      "id": "b8c160c6-29a3-4b7d-ab78-e126206627b1",
      "name": "URLs to Monitor",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        60,
        140
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $json.result.host }}",
            "Days Left": "={{ $json.result.days_left }}",
            "Valid From": "={{ $json.result.valid_from }}",
            "Valid Till": "={{ $json.result.valid_till }}"
          },
          "schema": [
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Valid From",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Valid From",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Valid Till",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Valid Till",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Days Left",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Days Left",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "URL"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1TakDfkHpgB8qQcvy98mgUfEsEZGnIVNlkwqnsWhGDwI/edit?gid=0#gid=0",
          "__regex": "https:\\/\\/docs\\.google\\.com\\/spreadsheets\\/d\\/[0-9a-zA-Z\\-_]+.*\\#gid=([0-9]+)"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1TakDfkHpgB8qQcvy98mgUfEsEZGnIVNlkwqnsWhGDwI/edit?gid=0#gid=0"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5,
      "alwaysOutputData": true
    },
    {
      "id": "21c4d282-5bb4-4d34-8cad-28e4e91843be",
      "name": "Fetch URLs",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -640,
        400
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1TakDfkHpgB8qQcvy98mgUfEsEZGnIVNlkwqnsWhGDwI/edit?gid=0#gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1TakDfkHpgB8qQcvy98mgUfEsEZGnIVNlkwqnsWhGDwI/edit?gid=0#gid=0"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "3d6ebf5c-a89d-4890-ab64-01c6db1d8486",
      "name": "Check SSL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -380,
        400
      ],
      "parameters": {
        "url": "=https://ssl-checker.io/api/v1/check/{{ $json[\"URL\"].replace(/^https?:\\/\\//, \"\").replace(/\\/$/, \"\") }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "1b7427f1-41aa-4aea-8a98-dccb44e958e0",
      "name": "Expiry Alert",
      "type": "n8n-nodes-base.if",
      "position": [
        60,
        620
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ee6e2ce8-569a-4f1f-91b5-2c55f605a16b",
              "operator": {
                "type": "number",
                "operation": "lte"
              },
              "leftValue": "={{ $json.result.days_left }}",
              "rightValue": 7
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8efd16a5-ff9e-4138-aa70-ebd087fb27ef",
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        360,
        400
      ],
      "parameters": {
        "html": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <style>\n        body {\n            font-family: Arial, sans-serif;\n            background-color: #f4f4f9;\n            color: #333;\n            margin: 0;\n            padding: 0;\n        }\n        .container {\n            width: 100%;\n            max-width: 600px;\n            margin: 20px auto;\n            padding: 20px;\n            background-color: #ffffff;\n            border-radius: 8px;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n        }\n        .header {\n            text-align: center;\n            color: #4CAF50;\n        }\n        .header h1 {\n            font-size: 24px;\n            margin: 0;\n        }\n        .message {\n            font-size: 16px;\n            margin: 20px 0;\n            padding: 10px;\n            background-color: #e3f2fd;\n            border-left: 5px solid #2196F3;\n        }\n        .highlight {\n            color: #d32f2f;\n            font-weight: bold;\n        }\n        .footer {\n            text-align: center;\n            font-size: 14px;\n            color: #888;\n            margin-top: 30px;\n        }\n        .footer a {\n            color: #2196F3;\n            text-decoration: none;\n        }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <h1>SSL Certificate Expiry Notice</h1>\n        </div>\n        <div class=\"message\">\n            <p>Dear Team,</p>\n            <p>The SSL certificate for the website <strong>{{ $json.result.host }}</strong> is set to expire in <span class=\"highlight\">{{ $json.result.days_left }}</span> days.</p>\n            <p>Please take the necessary actions to renew the certificate and ensure uninterrupted service.</p>\n        </div>\n        <div class=\"footer\">\n            <p>Best regards,<br>The IT Operations Team</p>\n        </div>\n    </div>\n</body>\n</html>\n",
        "options": {},
        "subject": "=SSL Expiry - {{ $json.result.days_left }} Days Left - {{ $json.result.host }}",
        "toEmail": "=team1@gmail.com,team2@gmail.com",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "7ce561b1-1102-4fc1-972b-7dca1793e023",
      "name": "Daily Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -900,
        400
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "12d2c49f-9d56-4ace-bc06-82ea850df133",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1620,
        -380
      ],
      "parameters": {
        "width": 500,
        "height": 1240,
        "content": "## \ud83d\udd10 SSL Expiry Notifier (No Paid APIs)\n\n### \ud83d\udc64 Who is this for?\nThis workflow is designed for IT admins, DevOps engineers, and web professionals who need to **monitor SSL certificate expirations** across multiple domains \u2014 **without relying on paid APIs**.\n\n---\n\n### \ud83e\udde9 What It Does\n1. **Daily Trigger** runs the workflow every morning.\n2. **Google Sheets Integration** fetches the list of website URLs to monitor.\n3. **Free SSL API Check** (`ssl-checker.io`) is used to retrieve certificate validity data.\n4. **Certificate Details** (valid from, valid till, days left) are updated back into the same Google Sheet.\n5. **If Condition** checks if the SSL certificate expires in \u22647 days.\n6. **Email Alert** is sent automatically for soon-to-expire certificates.\n\n---\n\n### \u2699\ufe0f Setup Instructions\n1. **Google Sheets**:  \n   - Clone the sample sheet or use your own.  \n   - Update the Sheet URL in the `Fetch URLs` and `Update Sheet` nodes.  \n   - Ensure it contains a `URL` column.\n\n2. **Credentials**:  \n   - Connect your **Google account** (for Sheets) and **SMTP credentials** (for email notifications).\n\n3. **Customize**:  \n   - Change the alert threshold in the **IF node** (currently set to 7 days).  \n   - Modify recipient list and message style in the **Send Email** node.\n\n---\n\n### \ud83e\udde0 Notes\n- Uses **ssl-checker.io**, a **free public API** \u2014 no paid services needed.  \n- Flexible and self-hosted monitoring solution.  \n- Ideal for small teams managing multiple domains.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "68db9999-8a66-479f-8708-c2b9b6556a76",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1000,
        220
      ],
      "parameters": {
        "height": 320,
        "content": "### \ud83d\udd52 Daily Trigger\nRuns the workflow every day at 8:00 AM.  \nAdjust the time or frequency as needed using cron or interval settings.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b39cd547-196f-48ea-b7b5-8b09561032ce",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -700,
        220
      ],
      "parameters": {
        "height": 320,
        "content": "### \ud83d\udcc4 Fetch URLs\nReads website URLs from a Google Sheet.  \nMake sure the sheet has a column named `URL` containing the domains you want to monitor.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "455e64c4-38da-4965-bfd6-b11a699243b1",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        220
      ],
      "parameters": {
        "height": 320,
        "content": "### \ud83d\udd0d Check SSL\nQueries `ssl-checker.io` (free API) for SSL certificate data of each domain.  \nReturns valid_from, valid_till, days_left, and host info.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "51b3423d-ea6e-4878-9d2e-177e04222100",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        460
      ],
      "parameters": {
        "height": 300,
        "content": "### \u26a0\ufe0f Expiry Alert\nChecks if `days_left` is less than or equal to 7.  \nOnly domains that meet this condition will trigger an email alert.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "17cfd4d8-cbfe-46f0-bdf1-3a89f557200b",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        300,
        220
      ],
      "parameters": {
        "height": 320,
        "content": "### \ud83d\udce7 Send Email\nSends an email to the specified recipients if a certificate is expiring soon.  \nThe message includes days left and the domain name in an HTML template.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "64c0883c-223f-4276-886b-d9996aa099dd",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -60
      ],
      "parameters": {
        "height": 400,
        "content": "### \ud83d\udd04 Update Sheet\nUpdates the original Google Sheet with new certificate data:\n- Valid From\n- Valid Till\n- Days Left  \nMatches by URL to ensure correct row is updated.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f02670ca-1476-4eb6-acac-205630fa2b1c",
  "connections": {
    "Check SSL": {
      "main": [
        [
          {
            "node": "URLs to Monitor",
            "type": "main",
            "index": 0
          },
          {
            "node": "Expiry Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch URLs": {
      "main": [
        [
          {
            "node": "Check SSL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email": {
      "main": [
        []
      ]
    },
    "Expiry Alert": {
      "main": [
        [
          {
            "node": "Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Trigger": {
      "main": [
        [
          {
            "node": "Fetch URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Great — here’s a complete Workflow Description for your n8n Creator submission based on the JSON you shared:

Source: https://n8n.io/workflows/4643/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Security teams, DevOps engineers, vulnerability analysts, and automation builders who want to eliminate repetitive Nessus scan parsing, AI-based risk triage, and manual reporting. Designed for orgs fo

Email Send, HTTP Request, Google Sheets +1
Data & Sheets

This n8n workflow automatically finds apartments for rent in Germany, filters them by your city, rent budget, and number of rooms, and applies to them via email. Each application includes: A personali

HTTP Request, Google Drive, Email Send +1
Data & Sheets

👤 Who it’s for Blue Team leads, CISOs, and SOC managers who want automated visibility into threat metrics, endpoint alerts, and response actions — without needing a full SIEM or BI platform.

HTTP Request, Email Send, Google Sheets
Data & Sheets

Workflow Overview Zoom Attendance Evaluator with Follow-up is an n8n automation workflow that automatically evaluates Zoom meeting attendance and sends follow-up emails to no-shows and early leavers w

Zoom, Item Lists, HTTP Request +3
Data & Sheets

This workflow automatically monitors Amazon product prices, tracks price changes, and sends alerts when significant price fluctuations occur. Built with ScrapeOps' structured data API, it provides a r

Google Sheets, HTTP Request, Email Send