AutomationFlowsData & Sheets › Log Weekly SEO Technical Audits with Google Pagespeed, Search Console, and…

Log Weekly SEO Technical Audits with Google Pagespeed, Search Console, and…

Original n8n title: Log Weekly SEO Technical Audits with Google Pagespeed, Search Console, and Sheets

ByMalik Shahzad Awan @malikshahzadawan on n8n.io

This workflow runs manually or weekly to pull URLs from your site’s XML sitemaps, checks each URL’s HTTP status, Google PageSpeed Insights performance score, and Google Search Console indexing state, then appends the results to a Google Sheets technical audit log. Runs when…

Event trigger★★★★☆ complexity29 nodesHTTP RequestXMLGoogle Sheets
Data & Sheets Trigger: Event Nodes: 29 Complexity: ★★★★☆ Added:

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

This workflow follows the Google Sheets → HTTP Request 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": "SEO Technical Audit",
  "nodes": [
    {
      "id": "9bb70532-f7ca-4ff9-b6cd-ba2b19834e0c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2208,
        -288
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## SEO Technical Audit\n\n### How it works\n\nThis workflow runs a technical SEO audit for a configured website either manually or on a weekly schedule. It fetches page and post sitemaps, extracts URLs, then checks each URL for HTTP status, PageSpeed score, and Google Search Console indexing status. The results are merged into audit rows and appended to a Google Sheet for reporting.\n\n### Setup steps\n\n- Set the target website URL in the Config node, and confirm the site exposes the expected /page-sitemap.xml and /post-sitemap.xml files.\n- Configure credentials or API access for the PageSpeed Insights request, including any required Google API key or query parameters.\n- Configure Google Search Console API credentials with access to the target property for the indexing inspection request.\n- Connect Google Sheets credentials and select the destination spreadsheet and sheet in the Append Audit Row node.\n- Adjust and activate the Weekly Schedule trigger if the audit should run automatically.\n\n### Customization\n\nChange the sitemap paths, audit cadence, PageSpeed strategy or metrics, and the Google Sheets destination columns to match the site and reporting needs."
      },
      "typeVersion": 1
    },
    {
      "id": "1c3e6b61-6247-422f-a5f6-798cdec1d7e2",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1648,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 480,
        "content": "## Triggers and config\n\nStarts the audit manually or on a weekly schedule, then sets the website URL used by the rest of the workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "ae58e1c0-4829-4166-86a6-66d55d7d0fe2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1248,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 304,
        "content": "## Fetch page sitemap\n\nRequests the page sitemap XML and parses it into structured data for downstream URL extraction."
      },
      "typeVersion": 1
    },
    {
      "id": "597d4563-2250-4861-8fec-55441f20ba08",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1248,
        160
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 320,
        "content": "## Fetch post sitemap\n\nRequests the post sitemap XML and parses it into structured data alongside the page sitemap branch."
      },
      "typeVersion": 1
    },
    {
      "id": "01f61aa7-b7fb-4138-8bb3-c82a8d0455c6",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 320,
        "content": "## Combine URL list\n\nAppends the parsed sitemap outputs together and flattens them into a URL list for parallel audit checks."
      },
      "typeVersion": 1
    },
    {
      "id": "a28b146d-fc8d-4b34-910e-03259d88ac15",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 304,
        "content": "## Check HTTP status\n\nRequests each discovered URL and extracts the URL and HTTP response status for the audit report."
      },
      "typeVersion": 1
    },
    {
      "id": "793fc721-6b8e-4668-b900-3aba73ed90f1",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        48
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 304,
        "content": "## Check PageSpeed score\n\nCalls the PageSpeed Insights API for each URL and normalizes the resulting PageSpeed score."
      },
      "typeVersion": 1
    },
    {
      "id": "45d07f23-929c-427f-9daa-85aa39480adb",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 304,
        "content": "## Check indexing status\n\nUses the Search Console API to inspect each URL and sets whether it is indexed."
      },
      "typeVersion": 1
    },
    {
      "id": "1f67370f-fefa-4e6f-9764-7ac17185382d",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 416,
        "content": "## Merge audit metrics\n\nCombines the HTTP status, PageSpeed, and indexing branches into a unified record per URL."
      },
      "typeVersion": 1
    },
    {
      "id": "cfeab93c-ed98-45a5-b695-477fd7fb372e",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 320,
        "content": "## Save audit report\n\nBuilds the final report row with URL, HTTP status, PageSpeed score, and indexed state, then appends it to Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "4a24ba9f-42cc-4f84-b4eb-fd3643040df2",
      "name": "Manual Execution Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1600,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "528631d2-8653-4123-861a-e338f3cb7142",
      "name": "Set Website URL",
      "type": "n8n-nodes-base.set",
      "notes": "Set this to your website URL (no trailing slash) before running.",
      "position": [
        -1440,
        80
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "cfg1",
              "name": "websiteUrl",
              "type": "string",
              "value": "https://example.com"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "84cb4809-02d2-4ed3-b942-05d21023ae9e",
      "name": "Fetch Page Sitemap",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1200,
        -40
      ],
      "parameters": {
        "url": "={{ $json.websiteUrl }}/page-sitemap.xml",
        "options": {}
      },
      "typeVersion": 4.4
    },
    {
      "id": "e19aec03-d7a9-4ae5-a2c7-0d1f07175efc",
      "name": "Fetch Post Sitemap",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1200,
        320
      ],
      "parameters": {
        "url": "={{ $json.websiteUrl }}/post-sitemap.xml",
        "options": {}
      },
      "typeVersion": 4.4
    },
    {
      "id": "6c556739-f674-41b7-8d57-8adc03eb8c97",
      "name": "Weekly Audit Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1600,
        160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "4461fac4-f565-4cdb-bfd0-47e6ab911fb9",
      "name": "Parse Page Sitemap XML",
      "type": "n8n-nodes-base.xml",
      "position": [
        -960,
        -40
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "941194d0-78f2-4fea-b49b-dae32dbd24d3",
      "name": "Merge Sitemaps",
      "type": "n8n-nodes-base.merge",
      "position": [
        -720,
        80
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "0ba0b235-d5da-4cd0-9953-302d13c30796",
      "name": "Parse Post Sitemap XML",
      "type": "n8n-nodes-base.xml",
      "position": [
        -960,
        320
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "f9d5d2a4-2d9d-466d-81de-16ebbba20c5f",
      "name": "Extract URLs from Sitemaps",
      "type": "n8n-nodes-base.code",
      "position": [
        -480,
        80
      ],
      "parameters": {
        "jsCode": "const urls = [];\nfor (const item of $input.all()) {\n  const urlset = item.json.urlset;\n  if (!urlset || !urlset.url) continue;\n  const list = Array.isArray(urlset.url) ? urlset.url : [urlset.url];\n  for (const u of list) {\n    const locVal = Array.isArray(u.loc) ? u.loc[0] : u.loc;\n    if (locVal) urls.push({ json: { url: locVal } });\n  }\n}\nreturn urls;"
      },
      "typeVersion": 2
    },
    {
      "id": "fedcdbd5-8ba9-4e7d-9d77-f303125a3f46",
      "name": "Fetch URL Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -200,
        -160
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "fullResponse": true
            }
          }
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "aef06eba-7b86-45a7-b597-66eb9f369021",
      "name": "Set URL Status",
      "type": "n8n-nodes-base.set",
      "position": [
        40,
        -160
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "url",
              "type": "string",
              "value": "={{ $('Extract URLs from Sitemaps').item.json.url }}"
            },
            {
              "id": "a2",
              "name": "httpStatus",
              "type": "number",
              "value": "={{ $json.statusCode }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e6a81f9e-6802-4179-89bc-22d3c23eaec9",
      "name": "Combine Status and Speed",
      "type": "n8n-nodes-base.merge",
      "position": [
        280,
        -40
      ],
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "850592fb-0ee9-4e8b-b56a-2d2883de4aab",
      "name": "Fetch PageSpeed Score",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Requires a PageSpeed Insights API key (Generic Auth - Query Auth). Get one free from Google Cloud Console.",
      "position": [
        -192,
        176
      ],
      "parameters": {
        "url": "https://www.googleapis.com/pagespeedonline/v5/runPagespeed",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 4000
            }
          },
          "response": {
            "response": {
              "neverError": true
            }
          }
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "url",
              "value": "={{ $json.url }}"
            },
            {
              "name": "category",
              "value": "performance"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "f35fd45c-ab68-4fed-b9d2-a3bbaf7a4bd4",
      "name": "Set PageSpeed Score",
      "type": "n8n-nodes-base.set",
      "position": [
        48,
        176
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "b1",
              "name": "url",
              "type": "string",
              "value": "={{ $('Extract URLs from Sitemaps').item.json.url }}"
            },
            {
              "id": "b2",
              "name": "pagespeedScore",
              "type": "number",
              "value": "={{ Math.round((($json.lighthouseResult && $json.lighthouseResult.categories && $json.lighthouseResult.categories.performance && $json.lighthouseResult.categories.performance.score) || 0) * 100) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cc8d2c59-72e4-4f5a-9b3a-4657fa9ae1e0",
      "name": "Inspect URL Indexing",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Requires a Google API credential with Search Console access, and your site verified in Google Search Console.",
      "position": [
        -192,
        512
      ],
      "parameters": {
        "url": "https://searchconsole.googleapis.com/v1/urlInspection/index:inspect",
        "method": "POST",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 2000
            }
          },
          "response": {
            "response": {
              "neverError": true
            }
          }
        },
        "jsonBody": "={\n  \"inspectionUrl\": \"{{ $json.url }}\",\n  \"siteUrl\": \"{{ $('Set Website URL').first().json.websiteUrl }}/\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleApi"
      },
      "typeVersion": 4.4
    },
    {
      "id": "56633803-6525-4005-afe3-e1e0aa35d3c7",
      "name": "Set Indexing Status",
      "type": "n8n-nodes-base.set",
      "position": [
        48,
        512
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "c1",
              "name": "url",
              "type": "string",
              "value": "={{ $('Extract URLs from Sitemaps').item.json.url }}"
            },
            {
              "id": "c2",
              "name": "indexed",
              "type": "string",
              "value": "={{ ($json.inspectionResult && $json.inspectionResult.indexStatusResult && $json.inspectionResult.indexStatusResult.coverageState) || \"Unknown\" }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b791db16-3a9b-41fb-b353-9dd559e083bc",
      "name": "Consolidate All Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        520,
        80
      ],
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "66a21359-5972-4f82-b6e1-cb70b75fa427",
      "name": "Build Audit Row",
      "type": "n8n-nodes-base.set",
      "position": [
        760,
        80
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "d1",
              "name": "URL",
              "type": "string",
              "value": "={{ $('Extract URLs from Sitemaps').item.json.url }}"
            },
            {
              "id": "d2",
              "name": "HTTP Status",
              "type": "number",
              "value": "={{ $json.httpStatus }}"
            },
            {
              "id": "d3",
              "name": "PageSpeed Score",
              "type": "number",
              "value": "={{ $json.pagespeedScore }}"
            },
            {
              "id": "d4",
              "name": "Indexed",
              "type": "string",
              "value": "={{ $json.indexed }}"
            },
            {
              "id": "d5",
              "name": "Date Checked",
              "type": "string",
              "value": "={{ $now.toFormat(\"yyyy-LL-dd\") }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0ac3a862-6dbc-4c99-8725-3355f8b394c0",
      "name": "Append to Audit Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Create a Google Sheet with columns: URL, HTTP Status, PageSpeed Score, Indexed, Date Checked. Connect your own Google Sheets credential.",
      "position": [
        1000,
        80
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData"
        },
        "options": {},
        "resource": "sheet",
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Technical Audit"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Your Google Sheet (pick from list)"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Merge Sitemaps": {
      "main": [
        [
          {
            "node": "Extract URLs from Sitemaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set URL Status": {
      "main": [
        [
          {
            "node": "Combine Status and Speed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Audit Row": {
      "main": [
        [
          {
            "node": "Append to Audit Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Website URL": {
      "main": [
        [
          {
            "node": "Fetch Page Sitemap",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Post Sitemap",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch URL Status": {
      "main": [
        [
          {
            "node": "Set URL Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Page Sitemap": {
      "main": [
        [
          {
            "node": "Parse Page Sitemap XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Post Sitemap": {
      "main": [
        [
          {
            "node": "Parse Post Sitemap XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Indexing Status": {
      "main": [
        [
          {
            "node": "Consolidate All Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Set PageSpeed Score": {
      "main": [
        [
          {
            "node": "Combine Status and Speed",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Consolidate All Data": {
      "main": [
        [
          {
            "node": "Build Audit Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Inspect URL Indexing": {
      "main": [
        [
          {
            "node": "Set Indexing Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch PageSpeed Score": {
      "main": [
        [
          {
            "node": "Set PageSpeed Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Audit Schedule": {
      "main": [
        [
          {
            "node": "Set Website URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Page Sitemap XML": {
      "main": [
        [
          {
            "node": "Merge Sitemaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Post Sitemap XML": {
      "main": [
        [
          {
            "node": "Merge Sitemaps",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Combine Status and Speed": {
      "main": [
        [
          {
            "node": "Consolidate All Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Execution Trigger": {
      "main": [
        [
          {
            "node": "Set Website URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract URLs from Sitemaps": {
      "main": [
        [
          {
            "node": "Fetch URL Status",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch PageSpeed Score",
            "type": "main",
            "index": 0
          },
          {
            "node": "Inspect URL Indexing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow runs manually or weekly to pull URLs from your site’s XML sitemaps, checks each URL’s HTTP status, Google PageSpeed Insights performance score, and Google Search Console indexing state, then appends the results to a Google Sheets technical audit log. Runs when…

Source: https://n8n.io/workflows/17752/ — 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

Stay ahead of trends by automating your content research. This workflow fetches trending keywords from Google Trends RSS, extracts key insights from top articles, and saves structured summaries in Goo

XML, HTTP Request, Google Sheets
Data & Sheets

This workflow shows a low code approach to parsing an XML file and storing its contents in a Google Sheets spreadsheet.

HTTP Request, XML, Google Sheets +1
Data & Sheets

TrackCollect_deeper. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 80 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +1
Data & Sheets

This template is ideal for solo store owners, eCommerce marketers, automation beginners, or anyone using Shopify and Gmail who wants to recover lost revenue without coding.

HTTP Request, Gmail, Twilio +3
Data & Sheets

PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +3