AutomationFlowsWeb Scraping › Submit Sitemap Urls From Oncrawl to Google Indexing API and Indexnow

Submit Sitemap Urls From Oncrawl to Google Indexing API and Indexnow

ByPhilippe @traversac on n8n.io

This workflow enables the submission of business-critical URLs via the Google Indexing API and IndexNow.

Webhook trigger★★★★★ complexity43 nodesHTTP RequestXML
Web Scraping Trigger: Webhook Nodes: 43 Complexity: ★★★★★ Added:
Submit Sitemap Urls From Oncrawl to Google Indexing API and Indexnow — n8n workflow card showing HTTP Request, XML integration

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

This workflow follows the HTTP Request → XML 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": "iqzsVwRb6oJWbNf7",
  "meta": {
    "templateId": "8778"
  },
  "name": "\ud83c\udfc1 Submit URLs for IndexNow & Google Indexing API",
  "tags": [
    {
      "id": "kdQmRBKF7wEy7vAq",
      "name": "\ud83e\udde0 Indexation",
      "createdAt": "2025-12-08T18:43:20.371Z",
      "updatedAt": "2025-12-12T16:27:45.249Z"
    }
  ],
  "nodes": [
    {
      "id": "b28e0165-f964-46a3-b371-784d9852c8a7",
      "name": "Split In Batches (IndexNow \u2264500)1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        4736,
        3808
      ],
      "parameters": {
        "options": {},
        "batchSize": "={{ Math.min(($items('Config')[0].json.BATCH_SIZE || 500), 500) }}"
      },
      "typeVersion": 3
    },
    {
      "id": "7dacb2d5-c8b5-4f45-9fb9-234302bc1198",
      "name": "Wait (IndexNow jitter)1",
      "type": "n8n-nodes-base.wait",
      "position": [
        5424,
        3904
      ],
      "parameters": {
        "unit": "seconds",
        "amount": "={{ (0.25 + Math.random()*0.75).toFixed(2) }}"
      },
      "typeVersion": 1
    },
    {
      "id": "628192e3-9583-4234-8de1-6079843b29d0",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4416,
        3680
      ],
      "parameters": {
        "color": 7,
        "width": 1312,
        "height": 528,
        "content": "### IndexNow Autosubmitting\n* Gate: IndexNow: Is USE_INDEXNOW is true from Config?\n* Split in Batches: split in batch of 500 URLs max\n* Build IndexNow payload: description in the node name\n* IndexNow Submit: Submit the URLs to indexNow"
      },
      "typeVersion": 1
    },
    {
      "id": "ee76fb30-8747-4bb0-afa6-5e8d55dfb047",
      "name": "Get Orphan Pages",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3232,
        4560
      ],
      "parameters": {
        "url": "=https://app.oncrawl.com/api/v2/data/crawl/{{ $json.body.crawl.id }}/pages",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"offset\": 0,\n  \"limit\": 1000, \n  \"fields\":[\"url\",\"sources\"], \n  \"sort\": [\n    { \n      \"field\": \"url\", \n      \"order\": \"asc\" \n    }], \"oql\":{\"and\":[{\"field\":[\"depth\",\"has_no_value\",\"\"]},{\"or\":[{\"field\":[\"sources\",\"equals\",\"logs_cross_analysis\"]},{\"field\":[\"sources\",\"equals\",\"sitemaps\"]}]}]}}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "d6a3f138-7788-4659-af38-b90dbc961060",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2976,
        4272
      ],
      "parameters": {
        "color": 5,
        "width": 1200,
        "height": 464,
        "content": "## VariationA: Index orphan pages\n* API documentation: https://developer.oncrawl.com/#Data-API\n* OQL definition: Get orphan pages for both sitemaps & logs\n* Merge node: Merge Items that InnerJoin loc, url fields. This is useful to recover the lastmod from Orphan pages referenced into Sitemaps.\nInput1 should be: \"Assign mandatory sitemap fields\" Node\n\n### Next nodes\n* change \"Set Node\" name in the script variables"
      },
      "typeVersion": 1
    },
    {
      "id": "953de3b8-b42d-43e0-b735-1bc3b24a937c",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        624,
        3456
      ],
      "parameters": {
        "path": "97a1f054-d877-4677-9c79-f10b0092e086",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e266f6de-c458-4498-a3ef-137d6aaf1f03",
      "name": "Post - Get Sitemaps",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        3456
      ],
      "parameters": {
        "url": "=https://app.oncrawl.com/api/v2/projects/{{ $json.body.project.id }}/crawl_configs/discover_sitemaps",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"crawl_config\": {\n        \"name\": \"{{ $json.body.crawl.configuration.name }}\",\n        \"max_speed\": 1,\n        \"max_url\": 500000,\n        \"quota_type\": null,\n        \"max_depth\": 1000,\n        \"start_url\": \"URL/\",\n        \"seeds_type\": \"sitemaps\",\n        \"follow_links\": false,\n        \"follow_canonicals\": false,\n        \"follow_redirects\": false,\n        \"follow_alternates\": false,\n        \"user_agent\": \"OnCrawl\",\n        \"agent_kind\": \"mobile\",\n        \"full_user_agent\": null,\n        \"enable_sitemaps\": true,\n        \"sitemaps\": [],\n        \"allow_query_params\": true,\n        \"filter_query_params\": false,\n        \"reorder_query_params\": true,\n        \"query_params_list\": \"\",\n        \"crawl_subdomains\": false,\n        \"ai_content_analysis\": null,\n        \"fulltext_extraction_css_mode\": null,\n        \"fulltext_extraction_css_selectors\": null,\n        \"crawler_region\": null,\n        \"ignore_noindex\": false,\n        \"ignore_nofollow\": false,\n        \"trigger_coc\": false,\n        \"trigger_datastudio_export\": false,\n        \"js_rendering\": false,\n        \"headless\": {\n            \"flatten_shadow_dom\": false,\n            \"cwv_audits\": false\n        },\n        \"alternate_start_urls\": [],\n        \"extra_headers\": {},\n        \"http_auth\": null,\n        \"dns\": [],\n        \"notifications\": {\n            \"email_recipients\": [\n                \"Email\"\n            ],\n            \"custom_webhooks\": [\n                {\n                    \"url\": \"Your_Webhook\"\n                }\n            ]\n        },\n        \"adobe_analytics_params\": null,\n        \"google_search_console_params\": null,\n        \"at_internet_params\": null,\n        \"google_analytics_params\": null,\n        \"majestic_params\": null,\n        \"logs_cross_analysis\": null,\n        \"filters\": null,\n        \"robots_txt\": [],\n        \"custom_fields\": [],\n        \"user_input_files\": [],\n        \"user_seed_files\": [],\n        \"scenarios\": [\n            \"Scenario\"\n        ],\n        \"project_id\": \"{{ $json.body.project.id }}\",\n        \"whitelist_params_mode\": true,\n        \"strict_sitemaps\": false,\n        \"scraping\": {\n            \"ignore_outlinks_if_error\": false\n        }\n    }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": " application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "9b5eedb3-e9c2-453d-8b9d-22a6a57aa7e7",
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "position": [
        1488,
        3456
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a18caab8-d28b-4d42-8399-d95cbe1945f0",
              "name": "body.crawl.id",
              "type": "string",
              "value": "={{ $('Webhook').item.json.body.crawl.id }}"
            },
            {
              "id": "62b17339-0608-4e32-bdc7-f2842e80c830",
              "name": "SITE_URL",
              "type": "string",
              "value": ""
            },
            {
              "id": "f0e1185a-37b2-424d-9ee4-3c5c7cb4dfdf",
              "name": "SITEMAP_URL",
              "type": "string",
              "value": "={{ $json.results[0].url }}"
            },
            {
              "id": "4d32ab5c-66c2-4eb6-8f31-2eef77495c35",
              "name": "DAYS_BACK",
              "type": "number",
              "value": 7
            },
            {
              "id": "e9f9eccc-eaa4-4fbd-af28-12e33c26b01e",
              "name": "BATCH_SIZE",
              "type": "number",
              "value": 500
            },
            {
              "id": "b3ac1b81-77f0-4081-892f-d92f7029a11b",
              "name": "USE_GOOGLE",
              "type": "boolean",
              "value": true
            },
            {
              "id": "b435a0dc-3ec5-4161-a9e0-416869d8c6e5",
              "name": "USE_INDEXNOW",
              "type": "boolean",
              "value": true
            },
            {
              "id": "2481f0c9-dc4f-44dc-97c7-b597bede50f6",
              "name": "INDEXNOW_KEY",
              "type": "string",
              "value": ""
            },
            {
              "id": "d48a7a0f-a2f9-41a9-904e-e5b5686c0e2a",
              "name": "INDEXNOW_KEY_URL",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "e6e4f92b-2c72-43a6-83b3-809c5f3f255e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        944,
        3072
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 576,
        "content": "### Call to Discover_sitemaps endpoint\nThis endpoint checks the Sitemaps declared in your Robots.txt file.\n- doc: https://developer.oncrawl.com/\n \n"
      },
      "typeVersion": 1
    },
    {
      "id": "dacf4691-0607-4e5c-87c0-37d23fd331fc",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        2960
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 688,
        "content": "### Config File\n**You MUST** update these variables:\n* SITE_URL\n* SITEMAP_URL: Fo subdomain sitemaps, you can duplicate this field.\n* INDEXNOW_KEY: you can create it in the Bing Webmaster tools here https://www.bing.com/indexnow/getstarted \n* INDEXNOW_KEY_URL: it's usually your domain and the INDEXNOW_KEY: wwww.example.com/<INDEXNOW_KEY>\n\nVariables you can update depending on your specs:\n* DAYS_BACK: 7 by default.\n* BATCH_SIZE: 500 it's the default recommended by IndexNow\n* USE_GOOGLE, USE_INDEXNOW: by default it's true which means the process will run for both Google and IndexNow\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cd67138d-9527-4f92-80a6-d1c485a7d28c",
      "name": "Assign mandatory sitemap fields",
      "type": "n8n-nodes-base.set",
      "position": [
        3696,
        3456
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "name": "lastmod",
              "type": "string",
              "value": "={{ $json.lastmod }}"
            },
            {
              "name": "loc",
              "type": "string",
              "value": "={{ $json.loc }}"
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "bf72c629-fd76-4cfc-8fc4-48c6bb32cf0a",
      "name": "Filter: lastmod within DAYS_BACK",
      "type": "n8n-nodes-base.code",
      "position": [
        4016,
        3456
      ],
      "parameters": {
        "jsCode": "\n// $items('Config') \u2192 returns all items coming from the node named Config\n//[0] \u2192 takes the first item in that array\n// .json \u2192 accesses the JSON payload of that item\n//.DAYS_BACK \u2192 reads this field from the JSON\n// || 7 is a fallback. If DAYS_BACK is missing, null or undefined\n\nconst daysBack = $items('Config')[0].json.DAYS_BACK || 7;\n\n// Calculate the cutoff based on date Now and DAYS_BACK in ms\nconst cutoff = new Date(Date.now() - daysBack*24*60*60*1000);\n\n// // Get all incoming items and filter them\n// If i.json.lastmod exists \u2192 create a Date from it otherwise \u2192 set the value to null\nconst items = $items().filter(i => {\n  const lm = i.json.lastmod ? new Date(i.json.lastmod) : null;\n\n  // Filter lm > cutoff\n  // After filtering, keep only the fields we care about\n\n  return lm && lm >= cutoff;}).map(i => ({ json: { loc: i.json.loc, lastmod: i.json.lastmod } }));\n\n// Return the final list of items to the next node\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "1976aed2-0932-47c7-80c2-c70454ebb54d",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3248,
        3456
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "urlset.url"
      },
      "typeVersion": 1
    },
    {
      "id": "e6bb1efd-653c-4b0a-a0ea-01759909fbd3",
      "name": "Get sitemap.xml",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1920,
        3456
      ],
      "parameters": {
        "url": "={{ $json.SITEMAP_URL }}",
        "options": {}
      },
      "typeVersion": 4.1
    },
    {
      "id": "cf38189d-00b0-4187-942e-327de0f0c4af",
      "name": "Convert sitemap to JSON",
      "type": "n8n-nodes-base.xml",
      "position": [
        2128,
        3456
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "9addc25e-3e78-4372-8d77-a1df68877c1c",
      "name": "Get content-specific sitemaps",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2352,
        3456
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "sitemapindex.sitemap"
      },
      "typeVersion": 1
    },
    {
      "id": "9c14b6d7-d924-49ed-8f94-65cf2d25ebfc",
      "name": "Get content of each sitemap",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2576,
        3456
      ],
      "parameters": {
        "url": "={{ $json.loc }}",
        "options": {}
      },
      "typeVersion": 4.1
    },
    {
      "id": "fb866818-5bde-4922-afbf-168c9acb45d5",
      "name": "convert page data to JSON",
      "type": "n8n-nodes-base.xml",
      "position": [
        2800,
        3456
      ],
      "parameters": {
        "options": {
          "explicitArray": false
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e33bc3e0-f5bc-4264-bfa0-07531a7ca2b7",
      "name": "Force urlset.url to array",
      "type": "n8n-nodes-base.set",
      "position": [
        3024,
        3456
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "name": "urlset.url",
              "type": "array",
              "value": "={{ $json.urlset && $json.urlset.url ? ($json.urlset.url[0] ? $json.urlset.url : [$json.urlset.url]) : [] }}"
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "477bd95e-2587-4273-a444-1a4f70504661",
      "name": "Sort",
      "type": "n8n-nodes-base.sort",
      "position": [
        3472,
        3456
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "order": "descending",
              "fieldName": "lastmod"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fe04aa09-a5cd-45fc-a9f9-fcd25a354a68",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1824,
        3152
      ],
      "parameters": {
        "color": 7,
        "width": 2032,
        "height": 496,
        "content": "### Parsing the sitemap and generating a list of the urls order by last modification date.\n* No need to edit anything here"
      },
      "typeVersion": 1
    },
    {
      "id": "bc4ddb14-7fa7-4d15-9b35-4cb0ec1e32a2",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3888,
        3152
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 496,
        "content": "### Filter to prevent API rate limiting issues\nCut-off calculation based on Now date -  Date set as DAYS_BACK"
      },
      "typeVersion": 1
    },
    {
      "id": "04805157-02f8-49d4-9ebb-09a191432b78",
      "name": "Build IndexNow payload",
      "type": "n8n-nodes-base.code",
      "position": [
        4976,
        3824
      ],
      "parameters": {
        "jsCode": "const batch = $items();\nif (!batch.length) return [];\n\n// 1) Pull & sanitize raw URLs \n\nlet urls = batch\n  .map(i => (i && i.json && i.json.loc) ? String(i.json.loc).trim() : null)\n  .filter(u => !!u); \n\n// 2) Keep only absolute http/https\nurls = urls.filter(u => /^https?:\\/\\//i.test(u));\n\n// 3) Ensure they match your site host (precompute host once)\nconst siteUrl = $items('Config')[0].json.SITE_URL || '';\nconst m = siteUrl.match(/^https?:\\/\\/([^/]+)/i);\nconst host = m ? m[1] : '';\n\n// If you prefer to pass HOST explicitly in Config, replace host above with:\n// const host = $items('Config')[0].json.HOST;\n\nurls = urls.filter(u => {\n  const h = (u.match(/^https?:\\/\\/([^/]+)/i) || [])[1] || '';\n  return h.toLowerCase() === host.toLowerCase();\n});\n\n// 4) De-dupe\nurls = Array.from(new Set(urls));\n\n// 5) Guard: IndexNow expects at least 1 valid URL\nif (!urls.length || !host) return [];\n\nreturn [{\n  json: {\n    host,\n    key: $items('Config')[0].json.INDEXNOW_KEY,\n    keyLocation: $items('Config')[0].json.INDEXNOW_KEY_URL,\n    urlList: urls\n  }\n}];\n\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "7049b17e-ac66-4ca7-b5da-0f4478655dc9",
      "name": "IndexNow Submit",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5184,
        3824
      ],
      "parameters": {
        "url": "https://api.indexnow.org/indexnow",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "fullResponse": true
            }
          }
        },
        "jsonBody": "={{ $json }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "retryOnFail": false,
      "typeVersion": 4.1
    },
    {
      "id": "a8a081fb-7435-4dae-9734-55afa2ab91cc",
      "name": "Gate: IndexNow",
      "type": "n8n-nodes-base.code",
      "position": [
        4496,
        3904
      ],
      "parameters": {
        "jsCode": "/**\u201cIf the Config node says USE_INDEXNOW is true, keep all items.\nIf not, output nothing.\u201d **/\n\nconst cfg = $items('Config')[0]?.json ?? {};\nconst on = (cfg.USE_INDEXNOW === true) || String(cfg.USE_INDEXNOW).toLowerCase() === 'true';\nreturn on ? $items() : [];"
      },
      "typeVersion": 2
    },
    {
      "id": "dfc0307b-0f1c-4079-9055-00e718377b12",
      "name": "Gate: Google",
      "type": "n8n-nodes-base.code",
      "position": [
        4544,
        3344
      ],
      "parameters": {
        "jsCode": "// Gate: Google\nconst cfg = $items('Config')[0]?.json ?? {};\nconst on = (cfg.USE_GOOGLE === true) || String(cfg.USE_GOOGLE).toLowerCase() === 'true';\nreturn on ? $items() : [];"
      },
      "typeVersion": 2
    },
    {
      "id": "ee667998-e924-4ed1-b7d4-fcd2726a382c",
      "name": "Wait2",
      "type": "n8n-nodes-base.wait",
      "position": [
        6096,
        3360
      ],
      "parameters": {
        "unit": "seconds",
        "amount": "={{ Math.min(1.5,0.3+3*Math.random()).toFixed(2) }}"
      },
      "typeVersion": 1
    },
    {
      "id": "df1131d8-87d2-47d4-b85a-d4e68c7d8bed",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        5296,
        3280
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "8e4a218a-6f67-48cb-b807-df17f003ce12",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.body.inspectionResult.indexStatusResult.coverageState }}",
                    "rightValue": "Submitted and indexed"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b91559f5-f49f-4bab-8e5b-ed74d4bd748a",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.body.inspectionResult.indexStatusResult.coverageState }}",
                    "rightValue": "Crawled - currently not indexed"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "4efd2e77-52ee-4912-9572-741be47902ec",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4432,
        2992
      ],
      "parameters": {
        "color": 7,
        "width": 1888,
        "height": 608,
        "content": "## Submit URLs to Google for indexing\n\nFor details, please check the Node documentation.\n- Gate: Is USE_GOOGLE is true from Config?\n- Loop_Over_Items: Fetch each URLs within the DAYS_BACK period range\n- Check_Status: We call the Google Search console endpoint to get the URLs Status in the Search Console\n- IsNew: Has a \"Submitted and indexed\" page get a lastModification more recent than the last Crawl date? If yes, we push it for indexation\n- Switch: If status is \"Not indexed\", We push the URL for indexation \n- Wait: Generates a random delay between 0.30 and 1.50 seconds, rounded to 2 decimals"
      },
      "typeVersion": 1
    },
    {
      "id": "843eeaa7-148a-4709-91c8-bd743ca263dd",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        4832,
        3344
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "ee0efb25-7742-4eda-8bc0-2a1dbac3938e",
      "name": "Check status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5088,
        3360
      ],
      "parameters": {
        "url": "=https://searchconsole.googleapis.com/v1/urlInspection/index:inspect",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "fullResponse": true
            }
          }
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "bodyParameters": {
          "parameters": [
            {
              "name": "inspectionUrl",
              "value": "={{ $json.loc }}"
            },
            {
              "name": "siteUrl"
            }
          ]
        }
      },
      "retryOnFail": false,
      "typeVersion": 4.1
    },
    {
      "id": "0c25fe18-e2b5-43f5-815b-5cb12d6ae4a9",
      "name": "is new?",
      "type": "n8n-nodes-base.if",
      "position": [
        5568,
        3200
      ],
      "parameters": {
        "options": {
          "looseTypeValidation": true
        },
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c8566fc4-57cf-4272-841e-014bb354a37d",
              "operator": {
                "type": "dateTime",
                "operation": "after"
              },
              "leftValue": "={{ $('Loop Over Items').item.json.lastmod }}",
              "rightValue": "={{ $json.body.inspectionResult.indexStatusResult.lastCrawlTime }}"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "de36c661-0a21-4a2e-bcf6-267029435256",
      "name": "URL Updated",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5776,
        3344
      ],
      "parameters": {
        "url": "=https://indexing.googleapis.com/v3/urlNotifications:publish",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "url",
              "value": "={{ $('Loop Over Items').item.json.loc }}"
            },
            {
              "name": "type",
              "value": "URL_UPDATED"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "2a45b2b1-10fc-412d-82b8-e1a2715c96af",
      "name": "Config - Orphan",
      "type": "n8n-nodes-base.set",
      "position": [
        3024,
        4560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a18caab8-d28b-4d42-8399-d95cbe1945f0",
              "name": "body.crawl.id",
              "type": "string",
              "value": "={{ $json.body.crawl.id }}"
            },
            {
              "id": "62b17339-0608-4e32-bdc7-f2842e80c830",
              "name": "SITE_URL",
              "type": "string",
              "value": "https://www.oncrawl.com"
            },
            {
              "id": "f0e1185a-37b2-424d-9ee4-3c5c7cb4dfdf",
              "name": "SITEMAP_URL",
              "type": "string",
              "value": "={{ $json.results[0].url }}"
            },
            {
              "id": "4d32ab5c-66c2-4eb6-8f31-2eef77495c35",
              "name": "DAYS_BACK",
              "type": "number",
              "value": 7
            },
            {
              "id": "e9f9eccc-eaa4-4fbd-af28-12e33c26b01e",
              "name": "BATCH_SIZE",
              "type": "number",
              "value": 500
            },
            {
              "id": "b3ac1b81-77f0-4081-892f-d92f7029a11b",
              "name": "USE_GOOGLE",
              "type": "boolean",
              "value": true
            },
            {
              "id": "b435a0dc-3ec5-4161-a9e0-416869d8c6e5",
              "name": "USE_INDEXNOW",
              "type": "boolean",
              "value": true
            },
            {
              "id": "2481f0c9-dc4f-44dc-97c7-b597bede50f6",
              "name": "INDEXNOW_KEY",
              "type": "string",
              "value": "aa9c53569e294278a9eb2cc8badd1aab"
            },
            {
              "id": "d48a7a0f-a2f9-41a9-904e-e5b5686c0e2a",
              "name": "INDEXNOW_KEY_URL",
              "type": "string",
              "value": "https://www.oncrawl.com/aa9c53569e294278a9eb2cc8badd1aab"
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "c40f4d40-46a1-440d-8d7e-9db21119d025",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        3936,
        4416
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "advanced": true,
        "mergeByFields": {
          "values": [
            {
              "field1": "loc",
              "field2": "url"
            }
          ]
        }
      },
      "typeVersion": 3.2,
      "alwaysOutputData": true
    },
    {
      "id": "1ca623f6-931c-42b7-90a0-739047ac7626",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2960,
        4864
      ],
      "parameters": {
        "color": 5,
        "width": 1200,
        "height": 464,
        "content": "## VariationB: Index newly added pages between a Crawl 1 & a Crawl2\n* API documentation: https://developer.oncrawl.com/#Data-API\n* OQL definition: Return added Indexable canonical pages in Crawl2\n* Merge node: Merge Items that match between loc, url fields. This is useful to recover the lastmod data for Google Node\nInput1 should be: \"Assign mandatory sitemap fields\" Node\n\n### Next nodes\n* change \"Set Node\" name in the script variables"
      },
      "typeVersion": 1
    },
    {
      "id": "224ca370-3175-445d-925e-fe4a3fb68193",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        496,
        3072
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 576,
        "content": "## Webhook\n* When crawl is over, a HTTP callback response is made to the N8N webhook URL.\n* doc: https://developer.oncrawl.com/#notification"
      },
      "typeVersion": 1
    },
    {
      "id": "2b5c90ae-5ca0-4687-bcc8-2257cdb1346c",
      "name": "Get Crawl over crawl",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3248,
        5136
      ],
      "parameters": {
        "url": "https://app.oncrawl.com/api/v2/data/crawl_over_crawl/69363a80468fbec0e7fe43ca/pages",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"offset\": 1,\n  \"limit\": 1000,  \n  \"oql\": {\n        \"and\": [\n            {\n                \"field\": [\n                    \"eq_fetched\",\n                    \"equals\",\n                    true\n                ]\n            },\n            {\n                \"or\": [\n                    {\n                        \"field\": [\n                            \"crawl1_meta_robots_index\",\n                            \"equals\",\n                            false\n                        ]\n                    },\n                    {\n                        \"field\": [\n                            \"crawl1_status_code_range\",\n                            \"equals\",\n                            [\n                                \"client_error\",\n                                \"redirect\",\n                                \"server_error\"\n                            ]\n                        ]\n                    },\n                    {\n                        \"field\": [\n                            \"crawl1_canonical_evaluation\",\n                            \"equals\",\n                            [\n                                \"not_matching\"\n                            ]\n                        ]\n                    }\n                ]\n            },\n            {\n                \"or\": [\n                    {\n                        \"field\": [\n                            \"crawl2_meta_robots_index\",\n                            \"equals\",\n                            true\n                        ]\n                    },\n                    {\n                        \"field\": [\n                            \"crawl2_status_code_range\",\n                            \"equals\",\n                            [\n                                \"ok\"\n                            ]\n                        ]\n                    },\n                    {\n                        \"field\": [\n                            \"crawl2_canonical_evaluation\",\n                            \"equals\",\n                            [\n                                \"matching\"\n                            ]\n                        ]\n                    }\n                ]\n            }\n        ]\n    }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "cd1fb27f-a26f-46a0-9b16-a28bc11b5adc",
      "name": "Split Out - Orphan1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3456,
        4560
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "urls"
      },
      "typeVersion": 1
    },
    {
      "id": "5f49e07f-b0a8-4897-a7f0-c38fc1179393",
      "name": "Split Out - Orphan2",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3680,
        4560
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "url"
      },
      "typeVersion": 1
    },
    {
      "id": "467cd7d0-9709-446a-88d1-53a9c308281c",
      "name": "Split Out - Coc1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3664,
        5136
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "urls"
      },
      "typeVersion": 1
    },
    {
      "id": "2ecd3fcf-5770-442a-93d1-13a76d546b15",
      "name": "Merge1",
      "type": "n8n-nodes-base.merge",
      "position": [
        3904,
        5024
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "advanced": true,
        "mergeByFields": {
          "values": [
            {
              "field1": "loc",
              "field2": "url"
            }
          ]
        }
      },
      "typeVersion": 3.2,
      "alwaysOutputData": true
    },
    {
      "id": "a994315f-6a64-4272-af0f-78795a6eedbd",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        2896
      ],
      "parameters": {
        "width": 784,
        "height": 1088,
        "content": "## Try it out!\nAn SEO Workflow to get your most important pages indexed with Oncrawl.\n\nWhy is it important for SEO?\n- IndexNow is an open source protocol developped by Bing and Yandex. Many generative platform like Copilot, Perplexity, ChatGPT rely on the Bing Index to generate answers for their users. If your content isn\u2019t present in that index, you\u2019re missing a key opportunity for your brand and pages to be reused and cited in LLM-powered results.\n- In parallel, Google remains the dominant search engine, representing ~80% of global search traffic. Gemini is deeply integrated into Google\u2019s ecosystem and, when grounding is enabled, can leverage Google Search as an external retrieval source.\n\nSubmitting your most business critical pages is a quick win, so that Search Engines crawl and index those pages. \nWhen your content is available and up to date, it has a higher chance of being used as grounding material to generate accurate, relevant answers to user queries.\n\n\n### How it works\nThis workflow works for Oncrawl users with API access enabled in their plan.\nif you are not an Oncrawl users, please refer to: https://n8n.io/workflows/8778-workflow-for-submitting-changed-sitemap-urls-using-google-indexing-api-and-bing-indexnow/\n\nTo get an API Key, just go in your User Account profile > tokens > + Add API access token:\n- Description: any name\n- Scope: select all checkboxes\n- Click in Create token. Keep your API secret safe\n\n### To go further\nThis workflow includes two additional variations:\n- VariationA: Index orphan pages detected in sitemap.xml and submit them to Google and IndexNow.\n- VariationB: It spots newly released pages by leveraging Oncrawl Crawl over Crawl analysis. It identifies the added indexable canonical URL between a pre-release and a post-release crawl."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "683b0a07-6418-4461-bf8e-6e3fec28da47",
  "connections": {
    "Sort": {
      "main": [
        [
          {
            "node": "Assign mandatory sitemap fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait2": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config": {
      "main": [
        [
          {
            "node": "Get sitemap.xml",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "is new?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "URL Updated",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Post - Get Sitemaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "is new?": {
      "main": [
        [
          {
            "node": "URL Updated",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Sort",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "URL Updated": {
      "main": [
        [
          {
            "node": "Wait2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check status": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gate: Google": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gate: IndexNow": {
      "main": [
        [
          {
            "node": "Split In Batches (IndexNow \u2264500)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config - Orphan": {
      "main": [
        [
          {
            "node": "Get Orphan Pages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get sitemap.xml": {
      "main": [
        [
          {
            "node": "Convert sitemap to JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IndexNow Submit": {
      "main": [
        [
          {
            "node": "Wait (IndexNow jitter)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Check status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Orphan Pages": {
      "main": [
        [
          {
            "node": "Split Out - Orphan1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Coc1": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Post - Get Sitemaps": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Orphan1": {
      "main": [
        [
          {
            "node": "Split Out - Orphan2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Orphan2": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Get Crawl over crawl": {
      "main": [
        [
          {
            "node": "Split Out - Coc1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build IndexNow payload": {
      "main": [
        [
          {
            "node": "IndexNow Submit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert sitemap to JSON": {
      "main": [
        [
          {
            "node": "Get content-specific sitemaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait (IndexNow jitter)1": {
      "main": [
        [
          {
            "node": "Split In Batches (IndexNow \u2264500)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Force urlset.url to array": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "convert page data to JSON": {
      "main": [
        [
          {
            "node": "Force urlset.url to array",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get content of each sitemap": {
      "main": [
        [
          {
            "node": "convert page data to JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get content-specific sitemaps": {
      "main": [
        [
          {
            "node": "Get content of each sitemap",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign mandatory sitemap fields": {
      "main": [
        [
          {
            "node": "Filter: lastmod within DAYS_BACK",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter: lastmod within DAYS_BACK": {
      "main": [
        [
          {
            "node": "Gate: IndexNow",
            "type": "main",
            "index": 0
          },
          {
            "node": "Gate: Google",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split In Batches (IndexNow \u2264500)1": {
      "main": [
        [],
        [
          {
            "node": "Build IndexNow payload",
            "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 enables the submission of business-critical URLs via the Google Indexing API and IndexNow.

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

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

Never miss important website updates again! This workflow automatically tracks changes on dynamic websites (think React apps, JavaScript-heavy sites) and sends you instant email notifications when som

HTTP Request, Google Sheets, Gmail
Web Scraping

This template implements a recursive web crawler inside n8n. Starting from a given URL, it crawls linked pages up to a maximum depth (default: 3), extracts text and links, and returns the collected co

HTTP Request
Web Scraping

Use responsibly and follow local rules and regulations

HTTP Request, XML, Google Drive
Web Scraping

Crawl Space & Foundation Repair Intake AI - Vapi MVP (Client Template). Uses httpRequest, googleSheets. Webhook trigger; 14 nodes.

HTTP Request, Google Sheets
Web Scraping

A reliable, no-frills web scraper that extracts content directly from websites using their sitemaps. Perfect for content audits, migrations, and research when you need straightforward HTML extraction

HTTP Request, XML, Google Drive