AutomationFlowsData & Sheets › Automate Monthly SEO Ranking Reports via Email

Automate Monthly SEO Ranking Reports via Email

Original n8n title: Generate and Send Monthly Client Ranking Reports

Generate and send monthly client ranking reports. Uses googleSheets, @local-falcon/n8n-nodes-localfalcon, emailSend. Scheduled trigger; 11 nodes.

Cron / scheduled trigger★★★★☆ complexity11 nodesGoogle Sheets@Local Falcon/N8N Nodes LocalfalconEmail Send
Data & Sheets Trigger: Cron / scheduled Nodes: 11 Complexity: ★★★★☆ Added:

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
{
  "name": "Generate and send monthly client ranking reports",
  "nodes": [
    {
      "parameters": {
        "content": "## Generate and Send Monthly Client Ranking Reports\n\n**Who is this for:** SEO agencies who want to automate monthly client reporting with comprehensive ranking summaries.\n\n**What this workflow does:**\n1. Runs on the 1st of each month\n2. Fetches all scan data for the previous month\n3. Calculates monthly performance metrics\n4. Generates professional HTML report\n5. Sends personalized email to each client\n\n**How to set up:**\n1. Add your Local Falcon API credentials (get your key at https://www.localfalcon.com/api/credentials)\n2. Configure client emails in Google Sheets\n3. Add SMTP credentials for sending\n4. Customize the report template\n5. Activate the workflow\n\n**Requirements:**\n- Local Falcon account with API access\n- Google Sheet with client info (email, place_id)\n- SMTP email credentials\n\n**How to customize:**\n- Add your agency branding to reports\n- Include competitive analysis section\n- Attach PDF version of report\n- Add executive summary for stakeholders",
        "height": 520,
        "width": 460,
        "color": 5
      },
      "id": "sticky-main",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        100,
        -180
      ]
    },
    {
      "parameters": {
        "content": "### Step 1: Schedule\nRuns 1st of each month.",
        "height": 100,
        "width": 200
      },
      "id": "sticky-step1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        40,
        660
      ]
    },
    {
      "parameters": {
        "content": "### Step 2: Get Clients\nFetches client list from sheet.",
        "height": 100,
        "width": 200
      },
      "id": "sticky-step2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        300,
        660
      ]
    },
    {
      "parameters": {
        "content": "### Step 3: Get Data\nFetches each client's reports.",
        "height": 100,
        "width": 200
      },
      "id": "sticky-step3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        560,
        660
      ]
    },
    {
      "parameters": {
        "content": "### Step 4: Generate\nCreates HTML report.",
        "height": 100,
        "width": 200
      },
      "id": "sticky-step4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        820,
        660
      ]
    },
    {
      "parameters": {
        "content": "### Step 5: Send\nEmails report to client.",
        "height": 100,
        "width": 200
      },
      "id": "sticky-step5",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1080,
        660
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months",
              "triggerAtDayOfMonth": 1,
              "triggerAtHour": 9
            }
          ]
        }
      },
      "id": "schedule",
      "name": "1st of Each Month",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        140,
        440
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_CLIENT_SHEET_ID"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Clients"
        },
        "options": {}
      },
      "id": "get-clients",
      "name": "Get Client List",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        400,
        440
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "scan",
        "operation": "listReports",
        "additionalFields": {
          "limit": 100,
          "placeId": "={{ $json.place_id }}"
        }
      },
      "id": "get-reports",
      "name": "Get Client Reports",
      "type": "@local-falcon/n8n-nodes-localfalcon.localFalcon",
      "typeVersion": 1,
      "position": [
        660,
        440
      ],
      "credentials": {
        "localFalconApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const client = $('Get Client List').item.json;\nconst reports = $input.first().json.reports || [];\n\n// Calculate metrics\nconst avgRanks = reports.map(r => parseFloat(r.avg_rank)).filter(r => !isNaN(r));\nconst avgRank = avgRanks.length > 0 \n  ? (avgRanks.reduce((a, b) => a + b, 0) / avgRanks.length).toFixed(1) \n  : 'N/A';\nconst bestRank = avgRanks.length > 0 ? Math.min(...avgRanks).toFixed(1) : 'N/A';\nconst totalScans = reports.length;\n\nconst lastMonth = new Date();\nlastMonth.setMonth(lastMonth.getMonth() - 1);\nconst monthName = lastMonth.toLocaleString('default', { month: 'long', year: 'numeric' });\n\nconst html = `\n<html>\n<body style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">\n  <h1 style=\"color: #333;\">Monthly Ranking Report</h1>\n  <h2 style=\"color: #666;\">${monthName}</h2>\n  \n  <p>Hello ${client.client_name || 'Valued Client'},</p>\n  \n  <p>Here's your monthly Local Falcon ranking summary:</p>\n  \n  <div style=\"background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 20px 0;\">\n    <h3 style=\"margin-top: 0;\">Performance Summary</h3>\n    <p><strong>Average Rank:</strong> ${avgRank}</p>\n    <p><strong>Best Rank:</strong> ${bestRank}</p>\n    <p><strong>Total Scans:</strong> ${totalScans}</p>\n  </div>\n  \n  <p>For detailed reports and insights, log into your Local Falcon dashboard.</p>\n  \n  <p>Best regards,<br>Your SEO Team</p>\n  \n  <hr style=\"border: none; border-top: 1px solid #eee; margin: 20px 0;\">\n  <p style=\"color: #999; font-size: 12px;\">Powered by Local Falcon + n8n</p>\n</body>\n</html>`;\n\nreturn [{\n  json: {\n    clientEmail: client.email,\n    clientName: client.client_name,\n    subject: `Your Monthly Ranking Report - ${monthName}`,\n    html: html\n  }\n}];"
      },
      "id": "generate-report",
      "name": "Generate Monthly Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        920,
        440
      ]
    },
    {
      "parameters": {
        "fromEmail": "reports@youragency.com",
        "toEmail": "={{ $json.clientEmail }}",
        "subject": "={{ $json.subject }}",
        "emailType": "html",
        "html": "={{ $json.html }}"
      },
      "id": "send-email",
      "name": "Send Client Report",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1180,
        440
      ],
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "1st of Each Month": {
      "main": [
        [
          {
            "node": "Get Client List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Client List": {
      "main": [
        [
          {
            "node": "Get Client Reports",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Client Reports": {
      "main": [
        [
          {
            "node": "Generate Monthly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Monthly Report": {
      "main": [
        [
          {
            "node": "Send Client Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

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

Generate and send monthly client ranking reports. Uses googleSheets, @local-falcon/n8n-nodes-localfalcon, emailSend. Scheduled trigger; 11 nodes.

Source: https://github.com/local-falcon/n8n-templates/blob/3dd7676046b6b8efc3bda40821cc944664db80f2/templates/23-monthly-client-report-email.json — 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 workflow fully automates the reconciliation process between your Local Database transactions and Payment Gateway transactions. It compares both data sources, identifies mismatches, categorizes di

Google Sheets, Email Send
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