11 n8n SEO Workflows to Automate Repetitive Tasks

Build 11 n8n SEO workflows for Search Console, sitemaps, broken links, page speed and publishing checks, with node setups, clear outputs and failure handling.

Editorial policy

n8n SEO workflows are most useful when they collect evidence, apply a clear rule and put the result where someone can act on it. Start with a recurring job you already understand: checking important URLs, comparing Search Console periods or preparing a weekly report. Automating an unclear decision usually produces a faster stream of unclear tasks.

The eleven workflows below cover different decisions, from investigating lost clicks to verifying a newly published page. Each includes a node sequence, the data to keep and a failure condition to handle. You can reuse the collection nodes across several workflows rather than building eleven separate systems.

These are implementation recipes researched against current n8n and Google documentation, not claims of hands-on tests or import-ready templates. The examples use illustrative settings. Your credentials, site structure, API access and review rules still need configuring.

Build the shared n8n foundation

Use an n8n instance you can maintain, access to the relevant website and authorized credentials for each connected service. Store secrets in n8n credentials, not in Code nodes, exported workflow JSON or reporting sheets. A Google login alone does not grant access to every Search Console property.

Build each job around the same pattern:

Trigger → collect → validate → compare → store → route an action

Set the workflow timezone deliberately. For a scheduled workflow, save and publish it; a successful manual run does not establish that its schedule is running. The Schedule Trigger documentation explains the available intervals and timezone behavior.

Choose a workflow by the decision you need to make:

Workflow Input Useful output
Click declines Comparable Search Console periods A traffic investigation
Low CTR Segmented query/page performance A snippet review
Multiple pages per query Query-to-page observations A mapping review
Sitemap changes Complete XML snapshots Added or removed URL records
HTTP monitoring Important URL list An availability incident
Metadata changes HTML and response headers A changed-signal alert
Broken internal links Source-to-target link pairs A repair task with source pages
Page speed Repeatable lab measurements A performance investigation
Content refresh Editorial inventory and performance An owned editorial task
Post-publication checks Expected published URL and content A verified page or specific defect
Weekly digest Existing findings and run status A short decision report

Keep durable state in a small n8n Data Table, a reporting sheet or a database appropriate to the volume. Execution history is useful for debugging, but define your own baseline and unresolved-issue records.

A practical starting schema is site, job, url, segment, observed_at, source_status, previous_value, current_value, issue_key, owner and review_status. Use an exact stable key for updates; n8n's Google Sheets node supports Append or Update Row when a sheet is your destination.

Restrict URL collection to approved public hosts and paths. Treat a failed request, a complete empty result and an incomplete result as three different states. That distinction matters in almost every workflow below.

1. Flag meaningful Search Console click declines

Run a weekly comparison that opens an investigation when a page loses a meaningful amount of search traffic.

Schedule Trigger → HTTP Request → Code → Merge → If → Data Table → notification

In HTTP Request, use Google OAuth credentials authorized for the property and the https://www.googleapis.com/auth/webmasters.readonly scope. Send a JSON POST request to:

Plain text
https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query

Replace the encoded property with your own. An illustrative request for one completed week is:

JSON
{
  "startDate": "2026-09-21",
  "endDate": "2026-09-27",
  "dimensions": ["page"],
  "type": "web",
  "dataState": "final",
  "rowLimit": 25000,
  "startRow": 0
}

Repeat for September 14–20, keeping the property, search type and filters identical. These inclusive API dates use Pacific Time, independently of the n8n schedule's timezone. For ongoing runs, calculate equivalent completed periods rather than leaving these example dates fixed.

Follow the Search Analytics API reference for pagination: increase startRow by your page size until no more returned rows remain. Pagination does not remove Google's internal top-row limitations.

The response contains a rows array. Split or map that array into one item per row, assign keys[0] to url, then join the two periods by URL. Explicitly name the joined fields previousClicks and currentClicks. In a JavaScript Code node set to Run Once for All Items, this example selects a review list:

JavaScript
return $input.all()
  .filter(({ json: row }) =>
    Number.isFinite(row.previousClicks) &&
    Number.isFinite(row.currentClicks) &&
    row.previousClicks >= 100 &&
    row.previousClicks - row.currentClicks >= 30 &&
    row.currentClicks <= row.previousClicks * 0.75
  )
  .map(({ json: row }) => ({ json: {
    ...row,
    lostClicks: row.previousClicks - row.currentClicks,
    reviewStatus: 'investigate'
  }}));

The thresholds are illustrative triage rules, not SEO standards. Keep a missing row as unknown unless you have independently established zero activity; an absent top-row result is not sufficient evidence.

Store both date ranges, clicks, impressions, position and the source status with each finding. Check seasonality, demand and site changes before assigning a cause. A decline should create one review item, not rewrite the page automatically.

2. Build a low-CTR review queue

Use this workflow when pages receive impressions but their search listings may need closer inspection. Its output is a shortlist for snippet and intent review, rather than a general traffic alarm.

Completed performance pull → Split Out → Code → If → Append or Update Row

Request query, page, device and country dimensions, then map the response keys in that order. Compare the same segments between periods. A mobile non-brand query in one country should not inherit a desktop brand-query benchmark from another.

Calculate each group's CTR as total clicks divided by total impressions. Do not average row-level CTR percentages: a row with ten impressions should not carry the same weight as one with ten thousand. When impressions are zero or data is unavailable, leave the comparison undefined.

For example, a change from 4% CTR to 3% is a fall of one percentage point, or 25% relative to the earlier CTR. Include the underlying counts so the reviewer can judge whether that difference matters. Filter out very small samples using a threshold chosen for your site.

Write a task containing the query, URL, segment, periods, counts and comparison reason. Let the reviewer examine the search result and landing page before proposing a title or description change. A different query mix, changed position or search layout can explain the same aggregate CTR movement.

Use the CTR diagnosis guide for that investigation. Keep the collection and shortlist automated; record a separate decision to change, watch or dismiss the finding.

3. Review queries appearing for several pages

Several URLs appearing for one query can be useful or perfectly normal. The automation should identify candidates for a keyword-mapping review, not declare cannibalization from a row count.

Query/page performance pull → Code grouping → If → mapping review queue

Reuse the segmented data from workflow two. Build a grouping key from query, device, country, property and reporting period. Within each group, collect the distinct page URLs and their clicks, impressions and average positions.

Keep URL paths and meaningful query parameters intact. Removing every parameter or lowercasing an entire URL can merge pages that your site treats differently. Do not combine language variants merely because their titles look similar.

Flag groups with more than one materially visible page, using a minimum evidence threshold appropriate to your site. Retain the individual rows rather than adding impressions together and calling the result the query's unique audience. Pages can appear in the same search, and aggregation changes what the numbers represent.

The review row should answer three questions: which URLs appeared, whether their intended search tasks overlap, and whether the preferred landing page changed between comparable periods. A reviewer can then choose to clarify a page, improve internal links, investigate canonical signals or take no action.

An illustrative finding might show a category page and a tutorial sharing a query. Different intents may justify both pages. Do not let the workflow issue redirects, merge content or change canonicals based only on the presence of two URLs. Google’s returned rows are evidence to inspect, not a complete map of every query and page.

4. Detect sitemap additions and removals

A sitemap comparison helps answer what the site is currently submitting for discovery. It does not tell you which URLs Google has indexed.

Schedule Trigger → HTTP Request → XML → URL normalization → snapshot comparison → change queue

Fetch the sitemap as text and use the XML node in XML to JSON mode. Inspect its output before adding expressions: Explicit Root and Explicit Array affect whether entries are objects or arrays.

If the root is a sitemap index, collect its child sitemap locations and fetch those files before comparing page URLs. Follow nested indexes only within your approved hosts and a bounded depth/file count. Stop the run if those bounds are exceeded. For a downloaded Gzip sitemap, use the Compression node to decompress it, then convert the extracted binary to text before passing it to XML.

Create a normalized set of page locations, retaining the original location and source file for evidence. Compare that set with the previous complete snapshot:

Change Queue action
New location Add it to the appropriate page-verification job
Previously present location now absent Check whether removal was intentional
Changed last-modified value Record the change; verify its meaning before treating it as a content update

On the first successful run, seed the baseline instead of alerting on every URL. If a child file times out, returns an error or fails parsing, mark the run incomplete and preserve the earlier baseline. Never turn a partially fetched sitemap into a mass-removal alert.

Commit the new snapshot only after all required files succeed. Use the sitemap optimization guide to review URL selection and discovery issues. Treat a removal as something to investigate, not a reason to restore every URL automatically.

5. Monitor critical URLs for failures and redirects

Start with a small list of important landing pages, product pages and documentation entry points. Give each URL an owner and expected behavior; a retired page that should redirect is different from a checkout guide that must remain available.

Schedule Trigger → URL inventory → HTTP Request → Switch → incident record

For a status check, configure HTTP Request with GET and these options:

  • Turn Include Response Headers and Status on.
  • Turn redirect following off when you need to see the first response.
  • Turn Never Error on to classify HTTP errors as data.
  • Use a bounded timeout and request batches appropriate to the host.

The HTTP Request node reference documents these settings. Never Error handles HTTP status responses; a DNS failure, TLS problem or timeout still needs an explicit failure path.

Route unexpected 4xx and 5xx responses to investigation. For a redirect, retain its status and Location header, resolve relative locations against the requested URL, then check the destination in a separate bounded step. Record the chain and detect loops rather than treating a final 200 as proof that the original URL stayed unchanged.

For an intermittent failure, confirm with a limited retry before escalating. Keep both observations and the time between them. A 403 may be an access policy affecting this checker, while a 429 asks you to reduce request pressure; neither should silently become a missing page.

The task should include the requested URL, expected state, actual response, redirect destination and observation time. This is a focused availability monitor, not a substitute for a full site crawl or proof of how Googlebot sees the page.

6. Watch titles, canonicals and robots directives

A deployment can leave a page available while changing the signals you meant it to publish. Keep a snapshot of those signals and alert when a meaningful value changes.

URL inventory → HTTP Request → HTML → comparison → changed-signal queue

Fetch the HTML and retain the response headers. In the HTML node, choose Extract HTML Content and point it at the response's HTML string, commonly body when full response output is enabled. Verify the actual input field in your execution.

These extraction settings provide a useful starting point:

Output field CSS selector Return value
titles title Text, array
descriptions meta[name="description"] Attribute content, array
canonicals link[rel~="canonical"] Attribute href, array
robots meta[name="robots"], meta[name="googlebot"] Attribute content, array
headings h1 Text, array

Arrays preserve evidence of duplicate elements. Keep the requested URL alongside the extracted fields, and inspect X-Robots-Tag separately in the response headers. Resolve relative canonical URLs before comparing them with your intended destination.

Store a baseline on the first complete fetch. On subsequent runs, record old and new values, the response status and the deployment or observation time. A new noindex directive on an intended public landing page deserves investigation; an intentional title edit can simply be recorded.

These checks inspect fetched HTML. They do not execute the page's JavaScript, fully interpret robots.txt or prove that Google selected the declared canonical. If essential tags appear only after rendering, use a rendering-capable inspection path for that page and label the raw-HTML result accordingly. Do not overwrite a valid baseline with an empty extraction from an error page.

The useful output of a link checker is a repair location: the source page containing the link, its anchor text and the failing destination. A list of broken target URLs alone leaves someone to rediscover the source.

Source URL list → HTTP Request → HTML link extraction → unique target checks → repair queue

Begin with a bounded group of public source pages or an existing crawl export. Extract a[href] as an array of href attributes. Retain a source-to-target record for every link; extract anchor text too when your parsing setup can preserve the pairing reliably.

Resolve relative links against the document's effective base URL, including a valid HTML base element when present. Accept only HTTP(S) links on the approved origin. Remove fragment identifiers for network checks, but preserve query parameters unless your site's URL rules establish that they are equivalent. Skip mail, telephone and script links.

Deduplicate destination requests, then join their results back to all source pages. For example, one failed target may produce a single repair task listing five referring pages rather than five independent HTTP checks and five notifications.

Use workflow five's response classification. A confirmed 404 or 410 is different from an access restriction, timeout or rate limit. Preserve those uncertain states for investigation rather than reporting all non-200 responses as broken links.

Key the unresolved task by site and destination, with referring sources stored as evidence. Recheck the affected links after a repair and close the task only after a successful observation. This workflow finds problems within the pages you supplied; it cannot establish sitewide link coverage or find links created only in a rendered browser DOM from a plain HTML fetch.

8. Track page-speed regressions on key templates

Choose representative URLs for important templates, then repeat comparable measurements. Checking a product page, an article and a category page is more useful than assuming the homepage represents the entire site.

Schedule Trigger → template URL list → HTTP Request → metric extraction → baseline comparison

Call the PageSpeed Insights API with an HTTP GET request:

Plain text
https://www.googleapis.com/pagespeedonline/v5/runPagespeed

Set the query parameters url to the page being checked, strategy to mobile or desktop, and category to performance. Configure API credentials and quotas for recurring use; do not hardcode a secret into a shared workflow.

Extract the numeric measurements you intend to compare:

Response path What to store
lighthouseResult.audits["largest-contentful-paint"].numericValue Lab LCP in milliseconds
lighthouseResult.audits["cumulative-layout-shift"].numericValue Lab CLS, unitless
lighthouseResult.audits["total-blocking-time"].numericValue Lab TBT in milliseconds
lighthouseResult.lighthouseVersion Measurement version
lighthouseResult.fetchTime Measurement timestamp

Also retain the requested URL, final URL, strategy and available environment/configuration details. Compare the same template and device under comparable conditions. Confirm an apparent regression with repeat measurements, using a consistent aggregation rule such as the median of three comparable runs.

A single lab score can fluctuate. If an audit is missing or the API fails, store an unavailable result rather than a zero. Treat a changed Lighthouse version as context for the comparison.

These are laboratory measurements. TBT is not field INP, and this job does not establish whether real users pass Core Web Vitals. Keep field evidence separate; Google's documentation directs ongoing field-data use toward the CrUX APIs. The page-speed monitoring guide explains how to investigate a regression after the workflow flags it.

9. Maintain a content-refresh backlog

A traffic alert asks what changed. A refresh backlog asks which editorial work is justified, who owns it and what evidence the next revision needs. Join performance with an actual content inventory so those decisions remain separate.

CMS inventory → Merge with performance → review rules → Google Sheets → owner notification

Read stable fields from the CMS: content ID, canonical URL, topic, owner and a genuine editorial review date when available. Keep an automatic CMS modification timestamp separate; it may reflect formatting or system maintenance rather than a substantive update.

Join those records to longer, comparable Search Console periods by URL. Inspect unmatched records and duplicate URLs before calculating priorities. A join that duplicates one performance row across several CMS records can inflate the apparent opportunity.

Create a candidate when there is a concrete reason to review it: an important source changed, a product instruction became outdated, reader questions remain unanswered or a sustained performance change warrants investigation. Age alone should not trigger a rewrite.

A useful task might read: “Review the shipping-options section; the official policy changed. Owner: ecommerce editor. Evidence: source URL and current section. Traffic context: attached comparable periods.” That is more actionable than “Refresh this old post.”

Key the task by content ID and review reason. Update an existing unresolved item on the next run, preserving the reviewer's decision and notes. Use statuses such as act, watch or dismiss in your own workflow only after confirming the destination allows them.

The automation can prepare a brief or CMS draft after an authorized editorial decision. Preserve the live article's identity, record the substantive change and evaluate subsequent performance with context. A before-and-after difference does not prove the edit caused it.

10. Check new pages after publication

A CMS can report published while the public page is stale, incomplete or pointing to another canonical. Start the workflow with the expected result, not just the CMS status.

Publication webhook or queue → bounded retry → public-page checks → verification record

Store the content ID, expected canonical URL, title and a meaningful expected body passage when the publication event arrives. Fetch the public URL, follow and record any redirects, and check:

  • The expected H1 and substantive content are actually present.
  • The canonical matches the intended final URL.
  • HTML and response headers do not contain an unintended noindex directive.
  • Important links and images appear where expected, including image descriptions.

Reuse workflow six's HTML extraction, adding a selector for the article body that matches your site. If a cache or build delay serves an older version, keep verification pending and retry within a bounded window. Do not create a second CMS post to fix a delayed public response.

Maintain a separate later check for Google's indexed record. With authorized Search Console credentials, send a POST request to:

Plain text
https://searchconsole.googleapis.com/v1/urlInspection/index:inspect

An illustrative JSON body is:

JSON
{
  "inspectionUrl": "https://example.com/blog/new-guide/",
  "siteUrl": "sc-domain:example.com",
  "languageCode": "en-US"
}

Store the returned coverage state, indexing state, Google-selected canonical and last crawl time when present, together with the inspection timestamp. Keep unavailable fields empty and retain the source response.

The URL Inspection API reports Google's indexed version; it is not a live URL test or an indexing request. Schedule checks within the property's quota rather than polling every newly published page continuously. Do not use an ordinary blog workflow to assume eligibility for Google's separate Indexing API.

Keep public verification, Google inspection and any separately authorized indexing submission as different statuses. A page can pass your publication checks before Google has indexed it, and there is no fixed waiting period that guarantees inclusion.

11. Assemble a weekly SEO decision digest

Use the earlier workflows' stored findings to produce a short report about decisions and unresolved work. Avoid another pipeline that refetches every source and repeats all of its alerts.

Schedule Trigger → read completed job records → Aggregate → format → deliver → record delivery

Divide the digest into actions, changes and source health. For each important action, include the owner, reason, evidence URL, observation date and next review date. A resolved redirect issue and an unreviewed content candidate should not look like equally urgent new incidents.

Add a source-health table with the last successful run, reporting period, completion status and number of records inspected. If a Google request failed, say the performance data is unavailable for that run. An empty completed query result is different from a failed collection.

For example, “Three URL failures confirmed; two assigned, one awaiting ownership” gives the team a decision. “Site health declined” hides both the evidence and the work remaining. Do not add unrelated percentages or invent a traffic cause to make the report sound analytical.

Store a delivery key containing the site, reporting period and digest version. Check it before sending, record the provider's accepted delivery result and keep delivery failures separate from data failures. For external recipients, review the intended audience and remove confidential query, customer or execution details that do not belong in their report.

Make the workflows reliable before scaling

Start with one collection job and one output destination. Add another workflow when the first produces evidence someone can use, including when a source is unavailable.

Keep one record per unresolved issue

Use a key such as site + job + URL + segment + issue type. Store observations separately from the current issue state. Alert when an issue first appears, changes materially or becomes due for review; update the existing item while it remains unresolved.

A Data Table lookup followed by an upsert is useful persistence, but it is not automatically a concurrency lock. If runs can overlap, serialize the job or use a storage system with a unique key and an atomic claim. Advance a delivery marker only after the destination accepts the action, and reconcile uncertain writes before repeating them.

Make failures visible

Create a separate workflow starting with Error Trigger, then assign it as the error workflow in each job's settings. n8n's error-handling documentation explains the setup.

Handle partial failures too. If you deliberately allow an HTTP status error through for classification, the overall run may otherwise appear successful. Use explicit validation and Stop and Error when essential inputs are incomplete. Retry only appropriate transient failures, with a limit; respect rate-limit responses instead of repeatedly increasing request volume.

Verify a small pilot

Before expanding the schedule, use a small set of URLs you control. Confirm that a known good page, an intentionally redirected test URL and an intentionally missing test URL produce different records. Repeat the same observation and check that it does not open duplicate tasks. Simulate an unavailable source and confirm that the last good baseline survives.

Also verify the first scheduled execution, credential expiry behavior, field mappings and notification delivery. Escape untrusted page text before inserting it into an HTML report. Retain only the source evidence needed to explain a finding, and set an appropriate retention period for execution data.

Measure your own operating result: useful findings reviewed, duplicate alerts avoided and failed jobs noticed. Those observations tell you whether the workflow deserves expansion. More nodes and more automated actions are not a substitute for that evidence.

Put this guide into practice

Continue with the Screpy tools that match this article's workflow.

Related posts

Keep reading practical SEO guides from the Screpy blog.

View all posts