This workflow corresponds to n8n.io template #4625 — 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 →
{
"name": "Competitor Research: BrightData SERP API to Google Sheets Automation",
"nodes": [
{
"id": "b030f1ec-a894-4996-8af1-0bc94e0ce54c",
"name": "When clicking 'Execute workflow'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-1080,
20
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2277478f-05ca-4cb0-8307-f6e7342c801f",
"name": "Get Keywords from Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-800,
20
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=0",
"cachedResultName": "Keywords"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "1b1f2e2c-d2e5-4ac4-9521-7ea9f82875bf",
"name": "URL Encode Keywords",
"type": "n8n-nodes-base.code",
"position": [
-520,
20
],
"parameters": {
"jsCode": "const encode = encodeURIComponent; for (const item of $input.all()) { item.json.Keyword = encode(item.json.Keyword); } return $input.all();"
},
"typeVersion": 2
},
{
"id": "909de1db-a90d-475a-86a2-5ba9519820a5",
"name": "Process Keywords in Batches",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-220,
20
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "9584b867-e0d4-447b-9051-24cea36d7456",
"name": "Fetch Google Search Results",
"type": "n8n-nodes-base.httpRequest",
"position": [
100,
40
],
"parameters": {
"url": "https://api.brightdata.com/request",
"method": "POST",
"options": {
"redirect": {
"redirect": {}
}
},
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "zone",
"value": "serp_api1"
},
{
"name": "url",
"value": "=https://www.google.com/search?q={{ $json.Keyword }}"
},
{
"name": "format",
"value": "raw"
},
{
"name": "country",
"value": "= {{ $json['Target Country'] }}"
}
]
},
"genericAuthType": "httpHeaderAuth",
"queryParameters": {
"parameters": [
{
"name": "async",
"value": "true"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2,
"alwaysOutputData": true
},
{
"id": "51500526-1e34-4a13-be69-01dc2c97d23e",
"name": "Extract Competitor Data from HTML",
"type": "n8n-nodes-base.code",
"position": [
380,
40
],
"parameters": {
"jsCode": "const html = $input.first().json.data || ''; return [{json: {websiteName: 'demo', websiteUrl: 'https://example.com', websiteTitle: 'Example Title', websiteDescription: 'Example description'}}];"
},
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "stickyNote:0",
"name": "Workflow Start",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1080,
120
],
"parameters": {
"content": "This workflow is triggered manually by clicking 'Execute workflow'.\n\nIt fetches keywords and target countries from a Google Sheet to perform SERP analysis."
},
"typeVersion": 1
},
{
"id": "stickyNote:1",
"name": "Read Keywords",
"type": "n8n-nodes-base.stickyNote",
"position": [
-800,
120
],
"parameters": {
"content": "Reads data from the specified Google Sheet.\n\nExpects columns like 'Keyword' and 'Target Country'.\n\n**Remember to replace 'YOUR_GOOGLE_SHEET_ID' and 'YOUR_GOOGLE_SHEETS_CREDENTIAL_ID'.**"
},
"typeVersion": 1
},
{
"id": "stickyNote:2",
"name": "Encode Keywords",
"type": "n8n-nodes-base.stickyNote",
"position": [
-520,
120
],
"parameters": {
"content": "Encodes the 'Keyword' value using `encodeURIComponent`.\n\nThis is necessary to ensure keywords with special characters are correctly formatted for the URL."
},
"typeVersion": 1
},
{
"id": "stickyNote:3",
"name": "Batch Processing",
"type": "n8n-nodes-base.stickyNote",
"position": [
-220,
120
],
"parameters": {
"content": "Splits the list of keywords into smaller batches.\n\nThis helps manage the number of requests sent to the BrightData API at once, improving stability and handling potential rate limits."
},
"typeVersion": 1
},
{
"id": "stickyNote:4",
"name": "Fetch SERP Data",
"type": "n8n-nodes-base.stickyNote",
"position": [
100,
140
],
"parameters": {
"content": "Calls the BrightData SERP API to get search results for each keyword/country.\n\nUses the 'serp_api1' zone and constructs the Google search URL.\n\n**Remember to replace 'YOUR_BRIGHTDATA_CREDENTIAL_ID'.**"
},
"typeVersion": 1
},
{
"id": "stickyNote:5",
"name": "Extract Data (Placeholder)",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
140
],
"parameters": {
"content": "This node is intended to parse the HTML response from BrightData.\n\n**The current code is a placeholder.** You need to implement the logic to extract competitor websites, titles, descriptions, etc., from the HTML."
},
"typeVersion": 1
}
],
"active": false,
"settings": {},
"connections": {
"URL Encode Keywords": {
"main": [
[
{
"node": "Process Keywords in Batches",
"type": "main",
"index": 0
}
]
]
},
"Get Keywords from Sheet": {
"main": [
[
{
"node": "URL Encode Keywords",
"type": "main",
"index": 0
}
]
]
},
"Fetch Google Search Results": {
"main": [
[
{
"node": "Extract Competitor Data from HTML",
"type": "main",
"index": 0
}
]
]
},
"Process Keywords in Batches": {
"main": [
[
{
"node": "Fetch Google Search Results",
"type": "main",
"index": 0
}
],
[]
]
},
"When clicking 'Execute workflow'": {
"main": [
[
{
"node": "Get Keywords from Sheet",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2ApihttpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This template requires a self-hosted n8n instance to run.
Source: https://n8n.io/workflows/4625/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
TrackCollect_deeper. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 80 nodes.
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.
PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.
Product Ad Machine. Uses googleDrive, googleSheets, httpRequest, @ffmpeg-micro/n8n-nodes-ffmpeg-micro. Event-driven trigger; 60 nodes.
Basic AI SEO KW Research n8n DataForSEO Gumroad 030125. Uses googleSheets, googleDrive, httpRequest. Event-driven trigger; 56 nodes.