AutomationFlowsWeb Scraping › Scrape Instagram Profiles with Apify and Log Results to Google Sheets

Scrape Instagram Profiles with Apify and Log Results to Google Sheets

ByDr. Firas @drfiras on n8n.io

This workflow collects public Instagram usernames through an n8n form, scrapes profile and recent post metrics using Apify’s Instagram Profile Scraper, then upserts the results (including engagement rate and a high-profile flag) into a Google Sheets table. Receives Instagram…

Event trigger★★★★☆ complexity15 nodesForm TriggerHTTP RequestGoogle Sheets
Web Scraping Trigger: Event Nodes: 15 Complexity: ★★★★☆ Added:

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

This workflow follows the Form Trigger → Google Sheets 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": "guDupkOLwQHKLmHl",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Scrape Instagram profiles and log them to Google Sheets",
  "tags": [
    {
      "id": "65X2FhsWhCbnsWXq",
      "name": "scraping",
      "createdAt": "2026-07-17T12:01:33.359Z",
      "updatedAt": "2026-07-17T12:01:33.359Z"
    },
    {
      "id": "BDQCNxQKN4A7X8jf",
      "name": "apify",
      "createdAt": "2026-07-14T19:34:02.338Z",
      "updatedAt": "2026-07-14T19:34:02.338Z"
    },
    {
      "id": "FCJ5YztcFy5XxWUZ",
      "name": "instagram",
      "createdAt": "2026-07-16T11:16:09.522Z",
      "updatedAt": "2026-07-16T11:16:09.522Z"
    },
    {
      "id": "wPS89f8pvHV6tTxu",
      "name": "google-sheets",
      "createdAt": "2026-07-14T19:34:02.347Z",
      "updatedAt": "2026-07-14T19:34:02.347Z"
    }
  ],
  "nodes": [
    {
      "id": "ec410a2c-e03a-4280-847b-df6adaabe5ad",
      "name": "Provide Instagram Usernames",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        0,
        192
      ],
      "parameters": {
        "options": {},
        "formTitle": "Instagram profile scraper",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "Usernames",
              "placeholder": "e.g. nike, apify, nasa",
              "requiredField": true
            }
          ]
        },
        "formDescription": "Enter one or more public Instagram usernames (separated by commas or new lines) to scrape profile data and log it to Google Sheets."
      },
      "typeVersion": 2.6
    },
    {
      "id": "d6fbbbee-67e7-4e88-b37a-52549df863a9",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-actor",
              "name": "apify_actor_endpoint",
              "type": "string",
              "value": "apify~instagram-profile-scraper"
            },
            {
              "id": "cfg-posts",
              "name": "max_posts_to_analyze",
              "type": "number",
              "value": 3
            },
            {
              "id": "cfg-followers",
              "name": "min_followers_highlight",
              "type": "number",
              "value": 10000
            },
            {
              "id": "cfg-usernames",
              "name": "usernames_list",
              "type": "array",
              "value": "={{ $json.Usernames.split(/[\\n,]+/).map(u => u.trim().replace(\"@\", \"\")).filter(u => u.length > 0) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b1e204d8-6f8d-4528-adb1-79beebaf8ec1",
      "name": "Scrape Instagram Profiles via Apify",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 2,
      "position": [
        448,
        192
      ],
      "parameters": {
        "url": "={{ \"https://api.apify.com/v2/acts/\" + $json.apify_actor_endpoint + \"/run-sync-get-dataset-items\" }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ { \"usernames\": $json.usernames_list, \"resultsLimit\": $json.max_posts_to_analyze } }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.4,
      "waitBetweenTries": 2000
    },
    {
      "id": "d8f84e89-8774-4d1b-8cfa-d92f83bbe470",
      "name": "Format Scrape Error",
      "type": "n8n-nodes-base.set",
      "position": [
        896,
        384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e-username",
              "name": "username",
              "type": "string",
              "value": "ALL"
            },
            {
              "id": "e-fullname",
              "name": "fullName",
              "type": "string",
              "value": ""
            },
            {
              "id": "e-followers",
              "name": "followersCount",
              "type": "number",
              "value": 0
            },
            {
              "id": "e-follows",
              "name": "followsCount",
              "type": "number",
              "value": 0
            },
            {
              "id": "e-bio",
              "name": "biography",
              "type": "string",
              "value": "={{ $json.error?.message ?? \"Unknown Apify error\" }}"
            },
            {
              "id": "e-pic",
              "name": "profilePicUrl",
              "type": "string",
              "value": ""
            },
            {
              "id": "e-url",
              "name": "externalUrl",
              "type": "string",
              "value": ""
            },
            {
              "id": "e-private",
              "name": "isPrivate",
              "type": "boolean",
              "value": false
            },
            {
              "id": "e-verified",
              "name": "isVerified",
              "type": "boolean",
              "value": false
            },
            {
              "id": "e-postscount",
              "name": "postsCount",
              "type": "number",
              "value": 0
            },
            {
              "id": "e-caption",
              "name": "latestPostCaption",
              "type": "string",
              "value": ""
            },
            {
              "id": "e-likes",
              "name": "latestPostLikes",
              "type": "number",
              "value": 0
            },
            {
              "id": "e-comments",
              "name": "latestPostComments",
              "type": "number",
              "value": 0
            },
            {
              "id": "e-engagement",
              "name": "engagementRatePercent",
              "type": "number",
              "value": 0
            },
            {
              "id": "e-highprofile",
              "name": "isHighProfile",
              "type": "boolean",
              "value": false
            },
            {
              "id": "e-status",
              "name": "status",
              "type": "string",
              "value": "error"
            },
            {
              "id": "e-scrapedat",
              "name": "scrapedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1c197059-7b51-4b5a-adaa-e5a627806cfc",
      "name": "Combine Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        1120,
        176
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "902eb756-9343-4a77-92a7-827a16ae9c00",
      "name": "Has Profile Data",
      "type": "n8n-nodes-base.if",
      "position": [
        672,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.username }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f16eac93-1038-4709-8b46-d1d056f5e236",
      "name": "Format Scraped Profile",
      "type": "n8n-nodes-base.set",
      "position": [
        896,
        32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f-username",
              "name": "username",
              "type": "string",
              "value": "={{ $json.username }}"
            },
            {
              "id": "f-fullname",
              "name": "fullName",
              "type": "string",
              "value": "={{ $json.fullName }}"
            },
            {
              "id": "f-followers",
              "name": "followersCount",
              "type": "number",
              "value": "={{ $json.followersCount }}"
            },
            {
              "id": "f-follows",
              "name": "followsCount",
              "type": "number",
              "value": "={{ $json.followsCount }}"
            },
            {
              "id": "f-bio",
              "name": "biography",
              "type": "string",
              "value": "={{ $json.biography }}"
            },
            {
              "id": "f-pic",
              "name": "profilePicUrl",
              "type": "string",
              "value": "={{ $json.profilePicUrl }}"
            },
            {
              "id": "f-url",
              "name": "externalUrl",
              "type": "string",
              "value": "={{ $json.externalUrl ?? \"\" }}"
            },
            {
              "id": "f-private",
              "name": "isPrivate",
              "type": "boolean",
              "value": "={{ $json.isPrivate ?? false }}"
            },
            {
              "id": "f-verified",
              "name": "isVerified",
              "type": "boolean",
              "value": "={{ $json.isVerified ?? false }}"
            },
            {
              "id": "f-postscount",
              "name": "postsCount",
              "type": "number",
              "value": "={{ $json.postsCount ?? 0 }}"
            },
            {
              "id": "f-caption",
              "name": "latestPostCaption",
              "type": "string",
              "value": "={{ $json.latestPosts?.[0]?.caption ?? \"\" }}"
            },
            {
              "id": "f-likes",
              "name": "latestPostLikes",
              "type": "number",
              "value": "={{ $json.latestPosts?.[0]?.likesCount ?? 0 }}"
            },
            {
              "id": "f-comments",
              "name": "latestPostComments",
              "type": "number",
              "value": "={{ $json.latestPosts?.[0]?.commentsCount ?? 0 }}"
            },
            {
              "id": "f-engagement",
              "name": "engagementRatePercent",
              "type": "number",
              "value": "={{ $json.followersCount > 0 ? Math.round((($json.latestPosts?.[0]?.likesCount ?? 0) + ($json.latestPosts?.[0]?.commentsCount ?? 0)) / $json.followersCount * 10000) / 100 : 0 }}"
            },
            {
              "id": "f-highprofile",
              "name": "isHighProfile",
              "type": "boolean",
              "value": "={{ $json.followersCount >= $('Configuration').item.json.min_followers_highlight }}"
            },
            {
              "id": "f-status",
              "name": "status",
              "type": "string",
              "value": "scraped"
            },
            {
              "id": "f-scrapedat",
              "name": "scrapedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bf59de68-4d92-4940-b86f-1b75d480adc4",
      "name": "Format Unavailable Profile",
      "type": "n8n-nodes-base.set",
      "position": [
        896,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "u-username",
              "name": "username",
              "type": "string",
              "value": "={{ $json.username ?? $json.query ?? \"unknown\" }}"
            },
            {
              "id": "u-fullname",
              "name": "fullName",
              "type": "string",
              "value": ""
            },
            {
              "id": "u-followers",
              "name": "followersCount",
              "type": "number",
              "value": 0
            },
            {
              "id": "u-follows",
              "name": "followsCount",
              "type": "number",
              "value": 0
            },
            {
              "id": "u-bio",
              "name": "biography",
              "type": "string",
              "value": ""
            },
            {
              "id": "u-pic",
              "name": "profilePicUrl",
              "type": "string",
              "value": ""
            },
            {
              "id": "u-url",
              "name": "externalUrl",
              "type": "string",
              "value": ""
            },
            {
              "id": "u-private",
              "name": "isPrivate",
              "type": "boolean",
              "value": true
            },
            {
              "id": "u-verified",
              "name": "isVerified",
              "type": "boolean",
              "value": false
            },
            {
              "id": "u-postscount",
              "name": "postsCount",
              "type": "number",
              "value": 0
            },
            {
              "id": "u-caption",
              "name": "latestPostCaption",
              "type": "string",
              "value": ""
            },
            {
              "id": "u-likes",
              "name": "latestPostLikes",
              "type": "number",
              "value": 0
            },
            {
              "id": "u-comments",
              "name": "latestPostComments",
              "type": "number",
              "value": 0
            },
            {
              "id": "u-engagement",
              "name": "engagementRatePercent",
              "type": "number",
              "value": 0
            },
            {
              "id": "u-highprofile",
              "name": "isHighProfile",
              "type": "boolean",
              "value": false
            },
            {
              "id": "u-status",
              "name": "status",
              "type": "string",
              "value": "private_or_not_found"
            },
            {
              "id": "u-scrapedat",
              "name": "scrapedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a196c584-d637-463a-ab23-1cbf2d8687d5",
      "name": "Save Profile to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1344,
        192
      ],
      "parameters": {
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Profiles"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Instagram Profiles"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "27e2332e-c746-4d97-aff5-aec13e4c2cd1",
      "name": "Sticky Note 7b635746",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        -272
      ],
      "parameters": {
        "color": 4,
        "width": 620,
        "height": 1660,
        "content": "# Scrape Instagram profiles and log them to Google Sheets\n# \ud83d\udce5  [Open full documentation on Notion](https://automatisation.notion.site/Course-Scrape-Instagram-profiles-and-log-them-to-Google-Sheets-3a03d6550fd981b596e4ca67e1a3c679)\n\n## How it works\nSubmit one or more public Instagram usernames through a simple form. The workflow sends all usernames in a single batched call to an Apify Instagram scraper, checks whether each profile returned valid data, and logs the results (followers, bio, latest post engagement, high-profile flag) into Google Sheets. Existing rows are updated instead of duplicated, and private/not-found profiles or Apify errors are logged with a clear status instead of silently failing.\n\n## Setup\n1. Create (or confirm) an Apify credential of type Header Auth named \"Apify API\", with header `Authorization: Bearer YOUR_APIFY_TOKEN`.\n2. Connect your Google Sheets account and pick (or create) a spreadsheet + tab with these columns: username, fullName, followersCount, followsCount, biography, profilePicUrl, externalUrl, isPrivate, isVerified, postsCount, latestPostCaption, latestPostLikes, latestPostComments, engagementRatePercent, isHighProfile, status, scrapedAt.\n3. Open the \"Configuration\" node and adjust the Apify actor slug, number of latest posts to analyze, and the followers threshold used to flag high-profile accounts.\n4. Activate the form and share its URL, or trigger it manually to test.\n\n## Requirements\n- An Apify account with access to an Instagram profile scraper actor (paid API usage; check the actor page for pricing).\n- A Google account connected via the Google Sheets OAuth2 credential.\n\n## Customization\n- Swap the Apify actor slug in \"Configuration\" for any compatible Instagram scraper actor or your own Apify Task ID.\n- Add a Wait node before the HTTP request if you plan to run this on very large username lists to further respect Apify rate limits.\n- Extend \"Format Scraped Profile\" to log more fields returned by your chosen actor (e.g. business category, recent post images).\n\nNeed help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[![The AI Doctor](https://www.dr-firas.com/the-ai-doctor.png)](https://www.youtube.com/@DrFiras_AI)"
      },
      "typeVersion": 1
    },
    {
      "id": "a1e8c134-69b2-47ba-8a53-1593b56bfdfa",
      "name": "Sticky Note 7923a3bc",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        -192
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 156,
        "content": "### 1. Provide usernames\nForm accepts multiple usernames, comma or newline separated."
      },
      "typeVersion": 1
    },
    {
      "id": "8edae1ff-8dae-4ea2-88e7-c2145e7fb2c7",
      "name": "Sticky Note 8ae0f674",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 172,
        "content": "### 2. Configuration\nSingle place to adjust the Apify actor, post count, and follower threshold."
      },
      "typeVersion": 1
    },
    {
      "id": "1100b5c9-1abd-4623-afd6-08e51ad14a61",
      "name": "Sticky Note b6db527b",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        496,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 188,
        "content": "### 3. Scrape via Apify\nOne batched call for all usernames. Retries twice on failure; error output is logged, not lost."
      },
      "typeVersion": 1
    },
    {
      "id": "ef79cd20-6941-498c-b957-e1106365f722",
      "name": "Sticky Note ef5a19cb",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 668,
        "height": 240,
        "content": "### 4. Validate & format\nSplits into three outcomes: scraped, private/not found, or Apify error \u2014 each formatted to the same schema."
      },
      "typeVersion": 1
    },
    {
      "id": "973b5f60-cd70-46ab-a9b8-6d90f844496f",
      "name": "Sticky Note a6216780",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        -224
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 220,
        "content": "### 5. Save to Google Sheets\nUpsert by username: reruns update existing rows instead of creating duplicates."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "daf0c609-07e4-4ca4-89ac-c6304067a99f",
  "nodeGroups": [],
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Scrape Instagram Profiles via Apify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Results": {
      "main": [
        [
          {
            "node": "Save Profile to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Profile Data": {
      "main": [
        [
          {
            "node": "Format Scraped Profile",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Unavailable Profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Scrape Error": {
      "main": [
        [
          {
            "node": "Combine Results",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Format Scraped Profile": {
      "main": [
        [
          {
            "node": "Combine Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Unavailable Profile": {
      "main": [
        [
          {
            "node": "Combine Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Provide Instagram Usernames": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape Instagram Profiles via Apify": {
      "main": [
        [
          {
            "node": "Has Profile Data",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Scrape Error",
            "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.

Pro

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

About this workflow

This workflow collects public Instagram usernames through an n8n form, scrapes profile and recent post metrics using Apify’s Instagram Profile Scraper, then upserts the results (including engagement rate and a high-profile flag) into a Google Sheets table. Receives Instagram…

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

Automate LinkedIn lead generation by scraping comments from targeted posts and enriching profiles with detailed data

Form Trigger, HTTP Request, Google Sheets
Web Scraping

Automatically scrapes Google My Business listings using Apify's Google Maps Scraper, filters results to businesses with 1-star reviews, and exports structured lead data into a dedicated Google Sheet t

Form Trigger, HTTP Request, Google Sheets +1
Web Scraping

Google Maps Lead Generator v1. Uses @apify/n8n-nodes-apify, formTrigger, httpRequest, googleSheets. Event-driven trigger; 15 nodes.

@Apify/N8N Nodes Apify, Form Trigger, HTTP Request +1
Web Scraping

Users who want to automatically fetch and organize property listings from 99Acres and MagicBricks into Google Sheets without manual copying. Users submit search URLs via a form. The workflow uses Apif

Google Sheets, HTTP Request, Form Trigger
Web Scraping

This workflow is perfect for content strategists, SEO specialists, marketing agencies, and virtual assistants who need to quickly audit and collect blog content from client websites into a structured

Form Trigger, Google Sheets, HTTP Request