Apify to PostgreSQL, Instagram leads captured clean
Instagram lead sourcing gets messy fast. You find a profile, you copy a URL, you hunt for an email in a bio, and then you paste it somewhere “temporary” that becomes permanent.
This is where Apify PostgreSQL leads automation pays off. Digital marketers feel it when campaign timelines get tight. Sales teams feel it when follow-ups slip. Agency operators see it when “just one more list” turns into a weekly fire drill.
This workflow turns Instagram prospecting into a repeatable system: generate smarter searches, scrape profiles, extract contact details with AI, and upsert clean lead records into PostgreSQL. You’ll see what it does, what you need, and how it behaves in the real world.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Apify to PostgreSQL, Instagram leads captured clean
flowchart LR
subgraph sg0["When clicking ‘Test workflow’ Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking ‘Test workflow’", pos: "b", h: 48 }
n1@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields", pos: "b", h: 48 }
n2@{ icon: "mdi:robot", form: "rounded", label: "AI Agent", pos: "b", h: 48 }
n3@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Code"]
n6@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Out", pos: "b", h: 48 }
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request1"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Code1"]
n9@{ icon: "mdi:robot", form: "rounded", label: "Information Extractor", pos: "b", h: 48 }
n10@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model1", pos: "b", h: 48 }
n11@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Postgres"]
n5 --> n4
n8 --> n7
n2 --> n5
n12 --> n11
n6 --> n11
n1 --> n2
n4 --> n6
n7 --> n9
n11 --> n8
n3 -.-> n2
n10 -.-> n9
n9 --> n12
n0 --> n1
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n2,n9 ai
class n3,n10 aiModel
class n12 database
class n4,n7 api
class n5,n8 code
classDef customIcon fill:none,stroke:none
class n4,n5,n7,n8,n12 customIcon
The Problem: Instagram leads don’t stay clean
Manual Instagram prospecting usually starts with good intentions and ends with scattered data. You pull profiles from Google results, open each one, scan bios for contact details, then paste everything into a sheet that wasn’t designed to prevent duplicates. Later, someone tries to “clean it up” before outreach, which means re-checking profiles, fixing broken URLs, and guessing which entries are real. The worst part is the mental overhead. You stop trusting your own list, so you double-check everything, which steals time from actual outreach.
It adds up fast. Here’s where it breaks down in day-to-day work.
- You end up with duplicates because two people scrape the same niche on different days.
- Email addresses in bios are often formatted oddly, so manual copying misses them or grabs junk.
- Google results include a lot of non-target pages, which means wasted clicks and bad leads.
- Spreadsheets don’t enforce “one lead, one record,” so outreach gets inconsistent and hard to scale.
The Solution: Apify + AI scraping, stored safely in PostgreSQL
This n8n workflow automates the whole Instagram lead capture loop and stores the results where they stay reliable: your PostgreSQL database. You start by setting simple targeting inputs (platform, niche, country). An AI Agent then generates smart Google search queries for that niche, which helps you find profiles you wouldn’t think to search for manually. Apify scrapes Google results, the workflow expands and batches those URLs, then it cleans each profile link before scraping profile details with Apify’s Instagram Scraper. Finally, another AI step extracts contact details (especially emails) from bios, and n8n upserts the lead into PostgreSQL so existing records get updated instead of duplicated.
The workflow kicks off from a manual trigger while you test. After that, you can swap in a schedule to run daily. Data flows from “targeting inputs” to “query generation,” then through scraping and extraction, and lands in PostgreSQL as a consistent lead table you can actually build outreach on.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you want 200 new Instagram prospects a week in “beauty & hair” in the USA. Manually, even a quick process takes about 2 minutes per profile to open, skim, copy, and paste, plus a little cleanup later, which is roughly 6 to 7 hours weekly. With this workflow, you spend about 10 minutes setting the targeting inputs, then let the scrape and extraction run in the background. You still review the database, but now it’s spot-checking, not rebuilding the list.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Apify to run Google and Instagram scrapers
- PostgreSQL to store and deduplicate lead records
- OpenAI API key (get it from your OpenAI platform dashboard)
Skill level: Intermediate. You’ll connect accounts, paste API keys, and be comfortable checking a database table once.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
You set the targeting inputs. In the “Map Lead Inputs” step, you choose things like Instagram, a niche (for example beauty & hair), and a target country so the workflow doesn’t wander.
AI turns inputs into search queries. The AI Agent uses an OpenAI chat model to produce Google queries that are more specific than what most people type, which usually means cleaner search results.
Apify scrapes, then n8n batches the work. The workflow sends the query to Apify’s Google Search Scraper, expands the results into a list, then processes them in batches so you don’t overload external APIs.
Profiles get cleaned, scraped, and stored. Each URL is normalized, Apify’s Instagram Scraper pulls profile details, AI extracts contact info from the bio, and PostgreSQL upserts the record so you don’t get duplicates.
You can easily modify the niche, country, and quality filters to match your outreach goals. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Manual Trigger
Start the workflow with the manual trigger so you can test and iterate on lead capture inputs.
- Add or confirm the Manual Run Trigger node is present as the first node.
- Keep default settings (no parameters required) for Manual Run Trigger.
- Connect Manual Run Trigger to Map Lead Inputs.
Step 2: Connect Lead Input Mapping
Define the search inputs used to generate targeted Google queries for Instagram leads.
- Open Map Lead Inputs and add assignments for lead targeting fields.
- Set site to
instagram. - Set field_of_interest to
beauty & hair. - Set target_country to
USA. - Connect Map Lead Inputs to Query Builder Agent.
Step 3: Set Up the Query Builder AI
Generate a Google search query string tailored to your niche and country.
- Open Query Builder Agent and set Text to
=field of interest: {{ $json.field_of_interest }} target country: {{ $json.target_country }}. - Keep Prompt Type set to
define. - Ensure OpenAI Chat Assistant is connected as the language model for Query Builder Agent.
- Credential Required: Connect your openAiApi credentials in OpenAI Chat Assistant.
- Connect Query Builder Agent to Escape Query Script.
Step 4: Configure Scraping and URL Cleanup
Scrape Google results, expand the list, and normalize profile URLs for downstream scraping.
- In Escape Query Script, keep the provided JavaScript that escapes quotes in the query string.
- In Search Scraper Request, set URL to
https://api.apify.com/v2/acts/apify~google-search-scraper/run-sync-get-dataset-items?token=[CONFIGURE_YOUR_TOKEN]. - Set JSON Body to
={ "focusOnPaidAds": false, "forceExactMatch": false, "includeIcons": false, "includeUnfilteredResults": false, "maxPagesPerQuery": 20, "mobileResults": false, "queries": "{{ $json.escapedQuery }}", "resultsPerPage": 100, "saveHtml": false, "saveHtmlToKeyValueStore": true }. - Enable Send Body and set Specify Body to
json. - In Expand Results List, set Field to Split Out to
organicResults. - Connect Search Scraper Request → Expand Results List → Iterate Result Batches → Clean Profile URL.
- In Clean Profile URL, keep the JavaScript that removes a trailing slash from the url field.
[CONFIGURE_YOUR_TOKEN] in Search Scraper Request and Profile Scrape Request with your Apify token before running.Step 5: Scrape Profiles and Extract Contact Details
Scrape Instagram profiles and extract email addresses from biographies using an AI extractor.
- In Profile Scrape Request, set URL to
https://api.apify.com/v2/acts/apify~instagram-scraper/run-sync-get-dataset-items?token=[CONFIGURE_YOUR_TOKEN]. - Set JSON Body to
={ "addParentData": false, "directUrls": [ "{{ $json.cleanedUrl }}" ], "enhanceUserSearchWithFacebookPage": false, "isUserReelFeedURL": false, "isUserTaggedFeedURL": false, "resultsLimit": 2, "resultsType": "details", "searchLimit": 1, "searchType": "hashtag" }. - Open Extract Contact Details and set Text to
={{ $json.biography }}. - Keep Input Schema as provided to extract
Emailin JSON. - Ensure OpenAI Extractor Model is connected as the language model for Extract Contact Details.
- Credential Required: Connect your openAiApi credentials in OpenAI Extractor Model.
- Connect Clean Profile URL → Profile Scrape Request → Extract Contact Details.
Step 6: Configure Database Upsert
Save extracted leads into your PostgreSQL table with an upsert operation.
- Open Upsert Lead Records and set Operation to
upsert. - Set Schema to
publicand Table toInstagram_Leads_Beauty&Hair. - Map columns.value.email to
={{ $('Filter').item.json.output[0].Email }}. - Map columns.value.user_name to
={{ $('Profile Scrape Request').item.json.username }}. - Map columns.value.account_link to
={{ $('Profile Scrape Request').item.json.inputUrl }}. - Map columns.value.follower_count to
={{ $('Profile Scrape Request').item.json.followsCount }}. - Map columns.value.target_country to
={{ $('Map Lead Inputs').item.json.target_country }}and columns.value.field_of_interest to={{ $('Map Lead Inputs').item.json.field_of_interest }}. - Credential Required: Connect your postgres credentials in Upsert Lead Records.
- Connect Extract Contact Details → Upsert Lead Records → Iterate Result Batches.
$('Filter') for email, but no node named Filter exists in the workflow. Update the email mapping to the correct source from Extract Contact Details before running.Step 7: Test and Activate Your Workflow
Validate each step with manual execution, then activate for production.
- Click Execute Workflow on Manual Run Trigger to run the workflow end-to-end.
- Confirm Search Scraper Request returns results and Expand Results List outputs individual items.
- Verify Profile Scrape Request returns profile details and Extract Contact Details outputs an
Emailfield (orN/A). - Check that Upsert Lead Records inserts or updates records in
Instagram_Leads_Beauty&Hair. - When satisfied, toggle the workflow to Active for production use.
Common Gotchas
- Apify credentials can expire or need specific permissions. If things break, check your Apify token status in the Apify Console first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
About 30–60 minutes if your Apify, OpenAI, and Postgres accounts are ready.
No. You will mainly connect accounts and paste API keys. The included code steps are already built; you’re not expected to write new code.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenAI API costs (often a few cents per run, depending on volume) and Apify usage.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and it’s straightforward. Update the targeting values in the “Map Lead Inputs” (Edit Fields/Set) step, then the AI Agent will generate new search queries automatically. You can also add a follower minimum by inserting an If/Switch filter after the profile scrape. Common tweaks include collecting extra fields (like category keywords), limiting results per run, and writing leads into a CRM after the Postgres upsert.
Usually it’s an invalid or expired Apify token, so regenerate it and update the credential in n8n. It can also be a wrong actor/task configuration for the scraper you’re calling, or Apify rate limits when you push too many requests quickly. If failures happen mid-run, reduce batch size in the loop and try again. Also check that your Apify plan still has usage available, because “no remaining credits” looks like a random error when you’re in a hurry.
A lot. On n8n Cloud, the practical limit is your monthly executions and how you batch results; on self-hosted n8n there’s no fixed execution cap, it mostly depends on your server and your Apify/OpenAI usage. In real usage, teams often run a few hundred profiles per niche per day, then scale up once they’re happy with lead quality. If you want higher volume, smaller batches and more frequent runs tend to be more stable than one giant scrape.
Often, yes, because this workflow leans on batching, conditional logic, and multi-step processing that gets awkward (and expensive) in many Zapier-style setups. n8n is also easier to self-host, which matters when you’re doing lead gen at scale. That said, if you only want a tiny two-step flow like “new row in a sheet → send an email,” Zapier or Make can feel faster to set up. The real decider is volume and complexity. Talk to an automation expert if you want a quick recommendation based on your outreach target.
Once this is in place, your Instagram lead list stops being a fragile spreadsheet and starts acting like an actual database. Honestly, that alone makes outreach feel calmer.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.