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 →
{
"nodes": [
{
"id": "2490f7b5-3a4b-413a-9b94-3e6d2131ee3f",
"name": "\ud83d\udccb Workflow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1424,
192
],
"parameters": {
"width": 600,
"height": 772,
"content": "@[youtube](GZ4OrOt3HSY)\n\n# \ud83d\udd17 LinkedIn Group Members to Google Sheets\n## Premium & Verified Members Only\n\n**Purpose:** Automatically extract LinkedIn group members and filter for Premium/Verified profiles, then save to Google Sheets.\n\n**Features:**\n- \u2705 Pagination support for large groups\n- \u2705 Filters for Premium & Verified members only\n- \u2705 Auto-appends to Google Sheets\n- \u2705 Tracks follower count, headline, profile URL\n\n**Author:** ConnectSafely.ai\n**API Endpoint:** `api.connectsafely.ai/linkedin/groups/members`"
},
"typeVersion": 1
},
{
"id": "69e3a09c-ac22-4d33-af77-a55a49f5d3fc",
"name": "\u2699\ufe0f Configuration",
"type": "n8n-nodes-base.stickyNote",
"position": [
-672,
816
],
"parameters": {
"color": 4,
"width": 600,
"height": 280,
"content": "## \u2699\ufe0f Configuration Required\n\n### 1. API Credentials\n- Set up **HTTP Bearer YOUR_TOKEN_HERE** credential for ConnectSafely.ai API\n- Name: `ConnectSafelyAI Token`\n\n### 2. Google Sheets\n- Connect your **Google Sheets OAuth2** account\n- Create/select your target spreadsheet\n- Ensure columns match: Profile ID, First Name, Last Name, etc.\n\n### 3. Group ID\n- Update `groupId` in **Initialize Pagination** node\n- Default: `9357376` (Product Hunt Promotion Group)"
},
"typeVersion": 1
},
{
"id": "da23d6c6-d824-4100-9765-aa0b90d9662e",
"name": "\ud83c\udf10 API Details",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
192
],
"parameters": {
"color": 5,
"width": 400,
"height": 260,
"content": "## \ud83c\udf10 ConnectSafely.ai API\n\n**Endpoint:** POST `/linkedin/groups/members`\n\n**Request Body:**\n```json\n{\n \"groupId\": \"9357376\",\n \"count\": 50,\n \"start\": 0\n}\n```\n\n**Response includes:**\n- `members[]` - Array of member objects\n- `hasMore` - Boolean for pagination"
},
"typeVersion": 1
},
{
"id": "59781647-de59-4257-b65e-985758ae5bf6",
"name": "\ud83d\udd0d Filter Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": 6,
"width": 400,
"height": 324,
"content": "## \ud83d\udd0d Member Filtering\n\n**Premium/Verified Detection:**\n- `isPremium === true`\n- `isVerified === true`\n- `badges` includes 'premium'\n- `badges` includes 'verified'\n\n**Extracted Fields:**\n- Profile ID, Name, Headline\n- Public Identifier, Profile URL\n- Follower Count, Badges\n- Relationship Status, Creator flag"
},
"typeVersion": 1
},
{
"id": "355516e4-e434-4b63-88b0-7b5f05a582b4",
"name": "\ud83d\udcc4 Pagination Flow",
"type": "n8n-nodes-base.stickyNote",
"position": [
288,
800
],
"parameters": {
"color": 6,
"width": 304,
"height": 248,
"content": "## \ud83d\udcc4 Pagination Logic\n\n1. Start with `start: 0`\n2. Fetch 50 members per request\n3. If `hasMore === true`:\n - Loop back to HTTP Request\n - Increment `start` by 50\n4. If `hasMore === false`:\n - Proceed to Google Sheets"
},
"typeVersion": 1
},
{
"id": "0e9e28ce-6a7d-4fb6-9e5f-1f2fb6c1d356",
"name": "\ud83d\udcca Google Sheets",
"type": "n8n-nodes-base.stickyNote",
"position": [
464,
48
],
"parameters": {
"width": 380,
"height": 280,
"content": "## \ud83d\udcca Google Sheets Output\n\n**Columns:**\n| Column | Description |\n|--------|-------------|\n| Profile ID | Unique LinkedIn ID |\n| First Name | Member first name |\n| Last Name | Member last name |\n| Headline | Professional headline |\n| Profile URL | Direct profile link |\n| Follower Count | Number of followers |\n| Is Premium | Premium status |\n| Is Verified | Verification status |"
},
"typeVersion": 1
},
{
"id": "9507a1f1-9e36-4801-b65d-1ee22a37dc39",
"name": "Start Workflow",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-752,
496
],
"parameters": {},
"typeVersion": 1
},
{
"id": "71060dc7-36c4-43c8-bbf3-b5aacebd5bb5",
"name": "Initialize Pagination",
"type": "n8n-nodes-base.code",
"position": [
-528,
496
],
"parameters": {
"jsCode": "// Initialize pagination variables\n// Change groupId to target different LinkedIn groups\nreturn [\n {\n json: {\n groupId: \"9357376\", // Product Hunt Promotion Group\n count: 50, // Members per request (max 50)\n start: 0, // Starting offset\n hasMore: true, // Continue flag\n allMembers: [] // Accumulated results\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "9b64821f-85a7-4c4e-a81a-66e06324c515",
"name": "Fetch Group Members",
"type": "n8n-nodes-base.httpRequest",
"position": [
-304,
496
],
"parameters": {},
"credentials": {},
"typeVersion": 4.3
},
{
"id": "d67e262a-7ab6-4741-b733-697d6d12ea74",
"name": "Process & Filter Members",
"type": "n8n-nodes-base.code",
"position": [
-80,
416
],
"parameters": {
"jsCode": "// Get current pagination state from the previous Code node's output\nconst items = $input.all();\nconst firstItem = items[0].json;\n\n// Access the API response data (merged with pagination state)\nconst response = firstItem;\nconst members = response.members || [];\nconst hasMore = response.hasMore || false;\n\n// Get pagination info from workflow context\nconst currentStart = $('Initialize Pagination').first().json.start || 0;\nconst currentCount = $('Initialize Pagination').first().json.count || 50;\nconst groupId = $('Initialize Pagination').first().json.groupId;\nconst previousMembers = $('Initialize Pagination').first().json.allMembers || [];\n\n// Filter for premium or verified members\nconst filteredMembers = members.filter(member => {\n const isPremium = member.isPremium === true;\n const isVerified = member.isVerified === true;\n const hasPremiumBadge = member.badges && member.badges.includes('premium');\n const hasVerifiedBadge = member.badges && member.badges.includes('verified');\n \n return isPremium || isVerified || hasPremiumBadge || hasVerifiedBadge;\n});\n\n// Extract relevant fields from filtered members\nconst processedMembers = filteredMembers.map(member => ({\n profileId: member.profileId,\n firstName: member.firstName,\n lastName: member.lastName,\n fullName: member.fullName,\n headline: member.headline,\n publicIdentifier: member.publicIdentifier,\n profileUrl: member.profileUrl,\n followerCount: member.followerCount,\n isPremium: member.isPremium,\n isVerified: member.isVerified,\n badges: member.badges ? member.badges.join(', ') : '',\n relationshipStatus: member.relationshipStatus,\n creator: member.creator,\n fetchedAt: new Date().toISOString()\n}));\n\n// Combine with previous members\nconst allMembers = [...previousMembers, ...processedMembers];\n\n// Prepare next iteration or final output\nif (hasMore) {\n return [{\n json: {\n groupId: groupId,\n count: currentCount,\n start: currentStart + currentCount,\n hasMore: true,\n allMembers: allMembers,\n continueLoop: true,\n currentBatch: processedMembers\n }\n }];\n} else {\n return [{\n json: {\n groupId: groupId,\n hasMore: false,\n allMembers: allMembers,\n continueLoop: false,\n totalFiltered: allMembers.length,\n totalFetched: currentStart + members.length\n }\n }];\n}"
},
"typeVersion": 2
},
{
"id": "1cae57d9-650f-4a30-9b46-e813b9056661",
"name": "Continue Pagination",
"type": "n8n-nodes-base.code",
"position": [
368,
592
],
"parameters": {
"jsCode": "// Loop back with updated pagination state\nconst item = $input.first().json;\n\nreturn [{\n json: {\n groupId: item.groupId,\n count: item.count,\n start: item.start,\n hasMore: item.hasMore,\n allMembers: item.allMembers\n }\n}];"
},
"typeVersion": 2
},
{
"id": "138b1558-373c-4e92-a0e9-515faa956417",
"name": "Prepare for Sheets",
"type": "n8n-nodes-base.code",
"position": [
368,
368
],
"parameters": {
"jsCode": "// Split all members into individual items for Google Sheets\nconst allMembers = $input.first().json.allMembers || [];\n\nif (allMembers.length === 0) {\n return [];\n}\n\n// Return each member as a separate item\nreturn allMembers.map(member => ({ json: member }));"
},
"typeVersion": 2
},
{
"id": "40039a53-0a69-421d-ac5f-cfa54527ccee",
"name": "Append to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
592,
368
],
"parameters": {
"columns": {
"value": {
"Headline": "={{ $json.headline }}",
"Full Name": "={{ $json.fullName }}",
"Last Name": "={{ $json.lastName }}",
"First Name": "={{ $json.firstName }}",
"Is Premium": "={{ $json.isPremium }}",
"Profile ID": "={{ $json.profileId }}",
"Is Verified": "={{ $json.isVerified }}",
"Profile URL": "={{ $json.profileUrl }}",
"Follower Count": "={{ $json.followerCount }}",
"Public Identifier": "={{ $json.publicIdentifier }}",
"Relationship Status": "={{ $json.relationshipStatus }}"
},
"schema": [
{
"id": "Profile ID",
"type": "string",
"display": true,
"required": false,
"displayName": "Profile ID",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "First Name",
"type": "string",
"display": true,
"required": false,
"displayName": "First Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Last Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Full Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Full Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Headline",
"type": "string",
"display": true,
"required": false,
"displayName": "Headline",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Public Identifier",
"type": "string",
"display": true,
"required": false,
"displayName": "Public Identifier",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Profile URL",
"type": "string",
"display": true,
"required": false,
"displayName": "Profile URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Follower Count",
"type": "string",
"display": true,
"required": false,
"displayName": "Follower Count",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Is Premium",
"type": "string",
"display": true,
"required": false,
"displayName": "Is Premium",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Is Verified",
"type": "string",
"display": true,
"required": false,
"displayName": "Is Verified",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Relationship Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Relationship Status",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Profile ID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=1409852359",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/11Cs4xOauRZa2usYQ6KNoKCpGtRIIMM_Paywm8Uk8Zes/edit#gid=1409852359",
"cachedResultName": "Product Hunt Promotion Group - 9357376"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "11Cs4xOauRZa2usYQ6KNoKCpGtRIIMM_Paywm8Uk8Zes",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/11Cs4xOauRZa2usYQ6KNoKCpGtRIIMM_Paywm8Uk8Zes/edit?usp=drivesdk",
"cachedResultName": "Top AI Influencers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "64fd109a-bf44-476b-9d74-d63fc01e1851",
"name": "\u2705 Workflow Complete",
"type": "n8n-nodes-base.noOp",
"position": [
816,
368
],
"parameters": {},
"typeVersion": 1
},
{
"id": "cdead25e-f181-46ba-87de-6e6855be9f4b",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
112,
432
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "34346e59-7490-4177-b29f-7c1fe4f5d7be",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ $json.continueLoop }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
}
],
"connections": {
"If": {
"main": [
[
{
"node": "Prepare for Sheets",
"type": "main",
"index": 0
}
],
[
{
"node": "Continue Pagination",
"type": "main",
"index": 0
}
]
]
},
"Start Workflow": {
"main": [
[
{
"node": "Initialize Pagination",
"type": "main",
"index": 0
}
]
]
},
"Prepare for Sheets": {
"main": [
[
{
"node": "Append to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Append to Google Sheets": {
"main": [
[
{
"node": "\u2705 Workflow Complete",
"type": "main",
"index": 0
}
]
]
},
"Process & Filter Members": {
"main": [
[
{
"node": "If",
"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.
googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
Easily extract and organise group member details into a Google Sheet without manual data entry or complex scripting, saving hours of administrative work for team managers and community organisers. This workflow fetches member information from an API via HTTP requests, applies filters to refine the data, and appends it directly to your specified Google Sheet for real-time tracking and analysis. The key step involves initialising pagination in a code node to handle large datasets efficiently, ensuring all members are captured across multiple pages seamlessly.
Use this workflow when you need to periodically sync group rosters from external APIs into Google Sheets for reporting or compliance checks, such as updating membership lists for online communities. Avoid it for one-off exports where a simple CSV download suffices, or if your API lacks pagination support, which could lead to incomplete data pulls. Common variations include adding email notifications after updates or integrating with tools like Slack for alerts on new members.
About this workflow
Group-Members-Sheets. Uses httpRequest, googleSheets. Event-driven trigger; 15 nodes.
Source: https://github.com/ConnectSafelyAI/connectsafely-cookbook/blob/main/n8n/group-members-sheets.json — 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.
AI ImgGen. Uses manualTrigger, stickyNote, convertToFile, splitInBatches. Event-driven trigger; 21 nodes.
Google Maps Scraper. Uses manualTrigger, googleSheets, httpRequest, itemLists. Event-driven trigger; 20 nodes.
Google Maps Scraper No API. Uses manualTrigger, removeDuplicates, splitInBatches, limit. Event-driven trigger; 15 nodes.
Vini. Uses googleSheetsTrigger, splitInBatches, googleSheets, httpRequest. Event-driven trigger; 12 nodes.
Read Xml File And Store Content In Google Sheets. Uses manualTrigger, stickyNote, httpRequest, xml. Event-driven trigger; 10 nodes.