facebook-hashtag-search-scraper-with-business-contact-leads avatar

facebook-hashtag-search-scraper-with-business-contact-leads

Pricing

from $4.99 / 1,000 results

Go to Apify Store
facebook-hashtag-search-scraper-with-business-contact-leads

facebook-hashtag-search-scraper-with-business-contact-leads

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

Scrapier

Scrapier

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

6 days ago

Last modified

Share

Facebook Hashtag Scraper — Posts + Business Contact Leads

Scrape every public post under one or more Facebook hashtags, then turn each post's author into a sales lead by pulling their public Page's email, phone, website, Instagram handle, category, and audience size — in the same run. Every response is structured JSON: post text, engagement counts, media attachments, and an authorContact object per post, ready to pass straight to an LLM, load into a CRM import, or feed a lead-scoring pipeline. Provide your own Facebook session cookies once, queue as many hashtags as you want, and let the run finish with a clean, itemized dataset — one row per matching post, with the business-contact fields already merged in.

What is the Facebook Hashtag Scraper with Business Contact Leads?

It's a two-stage Actor: stage one authenticates to Facebook with your session cookies and walks a hashtag's post feed via Facebook's internal GraphQL search endpoint (SearchCometResultsInitialResultsQuery / SearchCometResultsPaginatedResultsQuery); stage two takes each post's author and — logged out, with no extra credentials — fetches their public Facebook Page and parses out contact details. No other hashtag scraper in this category folds both stages into one Actor run: you get the post and a ready-to-use lead record for whoever wrote it. A Facebook login cookie (c_user + xs, or a single fbCookie string) is required to run the hashtag search itself — the contact-enrichment stage does not need any login.

What you get, per hashtag:

  • 📝 Post content and metadata — text, post ID, canonical URL, creation time (both formatted and Unix timestamp)
  • ❤️ Engagement counts — reactions broken down by type, comments, shares, and video view count
  • 🖼️ Media attachments — photos, albums, shares, and video/Reels, with Reels enriched with full playback metadata
  • 🏢 Business contact leads — the post author's email, phone, website, Instagram, category, page likes and followers, pulled from their public Page
  • 🏪 Lead-qualification flagsisBusinessPage and hasContact, so you can filter for actionable leads without post-processing
  • 🎯 Bulk hashtag input — queue any number of hashtags (or full hashtag URLs) in one searchQueries array

What data can you get with the Facebook Hashtag Scraper?

The Actor returns two things bolted together in a single dataset row: the post itself, and — when contact enrichment is on — a business-contact lead for whoever posted it.

Result TypeExtracted FieldsPrimary Use Case
PostpostId, user, url, text, topReactions, commentsCount, sharesCount, videoViewCount, time, timestamp, attachmentsHashtag monitoring, content research, engagement tracking
Business contact leadauthorContact.email, authorContact.phone, authorContact.website, authorContact.instagram, authorContact.category, authorContact.pageLikes, authorContact.pageFollowers, isBusinessPage, hasContactSales prospecting, local-business outreach lists, market mapping by hashtag niche
Video / Reel attachmentattachments[].target, attachments[].styles, attachments[].media, plus full Reels playback metadata when the attachment is a videoVideo content analysis, creative research

Business contact leads

This is the part the ranked competitors for this hashtag search category don't do: neither of the other Facebook hashtag scrapers checked (see the comparison further down) enriches the post author into a contact record — they stop at the post. This Actor's contact.py module fetches the author's Page logged out (no cookies spent on it) and parses the returned HTML for a fixed set of structured fields, which are then trimmed into the authorContact object attached to every post row:

{
"authorContact": {
"email": "hello@brightsmiledental.com",
"phone": "+1 555-201-4477",
"website": "https://brightsmiledental.com",
"instagram": "https://www.instagram.com/brightsmiledental",
"category": "Dentist & Dental Office",
"pageLikes": 4820,
"pageFollowers": 5103
},
"isBusinessPage": true,
"hasContact": true
}

How contact fields are actually extracted (not guessed, not fabricated):

  • Email comes only from Facebook's own structured "Intro" card data — the INTRO_CARD_PROFILE_EMAIL block inside the page's embedded JSON payload. There is no free-text email regex run over the page, so a false email match (e.g., picking up someone else's address from a comment or an ad) is not a failure mode here — if the Page hasn't published an email in its Intro card, email comes back null.
  • Website and Instagram are read primarily from the same structured Intro-card items (INTRO_CARD_WEBSITE, INTRO_CARD_SOCIAL_CONTEXT / INTRO_CARD_OTHER_ACCOUNT). Instagram has a fallback: if the Intro card yields nothing, the parser regex-scans the entire page HTML for any instagram.com/<handle> string (contact_parser.py, extract_additional_fields_from_html). This fallback is unscoped — on pages that embed unrelated Instagram links (share widgets, suggested-account modules) it can occasionally return an Instagram handle that isn't the Page owner's own account.
  • Phone is read from a set of regex patterns — "phone_number":"…", "universal_number":"…", and tel:… — applied to the raw HTML, and this regex-derived value is checked before the properly scoped Intro-card phone. Because a Facebook Page's HTML also embeds "Related Pages" / sidebar content that carries its own phone_number JSON blobs, this ordering means the phone number attributed to a lead can, in rarer cases, belong to a different page shown elsewhere on the same document rather than the page being scraped. Treat authorContact.phone as best-effort and spot-check high-value leads.
  • Category, page likes, and page followers come from Facebook's own og:description meta tag and structured delegate_page fields — reliable when the Page is public, null when it isn't.
  • A field is never invented — a Page that publishes no contact details, or a personal profile with no Page at all, returns all seven authorContact fields as null, with isBusinessPage: false and hasContact: false.

Reel and video attachment metadata

When a post's attachment is a video (target.__typename == "Video"), the Actor makes a second, concurrent request per video (FBReelsRootWithEntrypointQuery, up to 8 in parallel) to pull the full Reels player payload and merges it into that attachment's styles and media objects — playback resolutions, DASH manifest URLs, captions availability, and the video's owning actor. Posts with photo, album, or link-share attachments keep the lighter base attachment shape (deduplication_key, target, style_list, styles, media, all_subattachments) without the Reels enrichment pass.

Why not build a Facebook hashtag + lead scraper yourself?

Meta's Graph API does not expose a public hashtag or keyword-search endpoint that third-party apps can call against arbitrary Pages and posts — access is scoped to Pages you already manage, and historical keyword/hashtag search endpoints for third parties have been deprecated. Anything that walks a public hashtag feed today has to talk to the same internal, unversioned GraphQL surface a browser uses, which means:

  • The query surface moves. The GraphQL operation names, doc_id values, and CSRF-style tokens (fb_dtsg, lsd, jazoest) this Actor extracts from the hashtag page's HTML and JS bundles (fb_helper.py) are not documented anywhere and change without notice — a hand-rolled script breaks the next time Facebook ships a build.
  • Anti-bot escalation is active and account-aware. Facebook ties session trust to IP stability; replaying a login cookie from a rotating or datacenter IP is one of the fastest ways to trigger an account-checkpoint lock. This Actor pins a single sticky residential exit IP for the whole authenticated run and detects checkpoint/lock pages instantly instead of retrying into a wall.
  • Proxy cost and session management compound. Getting stable results means maintaining cookie freshness, a proxy escalation strategy, and checkpoint detection — three separate engineering problems that have nothing to do with what you actually want, which is a list of posts and leads.

Build it yourself if you need a fully custom scraping pipeline you control end to end and have the ongoing engineering budget to track Facebook's internal API changes. Use this Actor if you want hashtag-driven leads today without maintaining that pipeline.

What's the difference between a hashtag post scraper and a lead-generation scraper?

A hashtag post scraper answers "who is posting about X" — it returns post text, engagement, and a bare author reference (name, ID, profile URL). A lead-generation scraper answers "how do I contact this business" — it returns structured contact fields for a known Page. Historically these were two different tools, because Facebook's post-search API and Page/About-tab data live in unrelated parts of the site with different access patterns. That distinction matters less now that hashtag campaigns are how many small businesses actually market themselves on Facebook: the person posting under #realestate or #plumber is frequently the business itself, and a reader monitoring a hashtag is often trying to build exactly the contact list a separate lead scraper would produce. This Actor returns both objects in one row — the post under text/topReactions/attachments, and the lead under authorContact — so you don't have to run a hashtag scraper and then feed its output into a second Page-contact scraper.

How to scrape Facebook hashtags for business leads

  1. Open the Actor's page on the Apify Store and click Try for free (or Run) to open it in the Apify Console, or call it via the Apify API / apify-client.
  2. Enter one or more hashtags in searchQueries — plain words (realestate) or full hashtag URLs (https://www.facebook.com/hashtag/realestate) both work.
  3. Set the real query controls the input exposes: maxItems (posts to collect per hashtag), extractContacts (turn contact enrichment on/off), businessPagesOnly and requireContact (lead-qualification filters).
  4. Paste your Facebook c_user and xs session cookies (or a single fbCookie header string) — required for the hashtag search stage.
  5. Start the run and download or stream results as JSON, JSONL, CSV, Excel, HTML table, or XML from the Storage tab, or pull them live via the Apify API as they're pushed.
{
"searchQueries": ["realestate", "plumber"],
"maxItems": 25,
"extractContacts": true,
"businessPagesOnly": true,
"requireContact": true
}

How to run multiple hashtags in one job

searchQueries is an array — add as many hashtags as you want in one input and the Actor processes them sequentially in the order given, applying the same maxItems, extractContacts, businessPagesOnly, and requireContact settings to every hashtag in the batch. There is no documented per-run concurrency setting for hashtags themselves (each hashtag's post pages are fetched one page at a time); the only parallelism the Actor exposes is the video/Reel-metadata enrichment step, which fetches up to 8 Reels concurrently per page of posts.

⬇️ Input

All fields are configured through the Actor's input schema in the Apify Console or passed as a JSON object via the API. Only searchQueries is required — everything else has a working default.

ParameterRequiredTypeDescriptionExample Value
searchQueriesYesarray (string list)One or more hashtags (realestate, plumber, coffeeshop) or full Facebook hashtag URLs (https://www.facebook.com/hashtag/realestate). Every matching post's author becomes a potential lead. Default ["football"].["realestate", "plumber"]
maxItemsNointegerMaximum posts to collect per hashtag — each is enriched into one lead row. Facebook caps a hashtag feed at roughly 200 posts. Minimum 1, maximum 10000, default 10.25
extractContactsNobooleanWhen on, each post author's public Page is fetched (logged-out) and parsed into authorContact. Turn off for a plain hashtag-post scrape without the contact lookup. Default true.true
businessPagesOnlyNobooleanOnly output posts whose author is a business Page (isBusinessPage = true); personal profiles are skipped and not charged. Default false.true
requireContactNobooleanOnly output leads whose Page exposes an email OR a phone number (hasContact = true). Default false.true
c_userNostringYour Facebook c_user cookie (numeric account ID). Copy from browser DevTools → Application → Cookies → www.facebook.com. Leave blank if you supply fbCookie instead."100000000000000"
xsNostring (secret)Your Facebook xs session cookie. Copy from the same DevTools panel. Leave blank if you supply fbCookie instead."34%3Aabcdefg..."
fbCookieNostring (secret)Full Facebook cookie header, e.g. c_user=1000...; xs=34%3A... — an alternative to filling c_user and xs separately; both values are parsed out of it."c_user=100...; xs=34%3A..."
proxyConfigurationNoobject (proxy editor)Apify Proxy configuration. Default {"useApifyProxy": false} in the schema; in practice the Actor still runs the authenticated hashtag search on a sticky Apify residential proxy unless you explicitly configure otherwise (see the proxy note below).{"useApifyProxy": false}

Full example input:

{
"searchQueries": ["realestate", "plumber", "coffeeshop"],
"maxItems": 25,
"extractContacts": true,
"businessPagesOnly": true,
"requireContact": true,
"c_user": "100000000000000",
"xs": "34%3Aabc123def456ghi789...",
"proxyConfiguration": { "useApifyProxy": false }
}

Common pitfalls:

  • Missing or expired cookies produce zero posts, not a failed run. Without valid c_user + xs (or fbCookie), the run finishes SUCCEEDED with a single uncharged diagnostic record explaining exactly what's missing — check that record's status field, don't rely on the run's overall status to tell you the scrape worked.
  • ⚠️ proxyConfiguration reads as "no proxy" by default, but the hashtag-search stage does not actually run proxy-free. The schema's default (useApifyProxy: false) describes what you configure; the Actor's proxy manager always opens the authenticated search on a sticky Apify residential IP regardless, because that's what keeps a real login session from tripping Facebook's IP-stability checks. If you explicitly turn on proxyConfiguration, your chosen groups are honoured but still pinned to one sticky session for the run.
  • If every hashtag you enter fails to normalize (empty strings, non-Facebook URLs), the run silently falls back to scraping #travel rather than erroring — double-check your searchQueries values if your dataset comes back full of unexpected hashtag results.
  • hasContact only checks email and phone — a lead with only a website or Instagram handle and no email/phone will not pass requireContact: true, even though it has some contact information.

⬆️ Output

Results are pushed live, one row per post, as typed and normalized JSON with a consistent schema across every run — no waiting for the whole hashtag to finish before rows start appearing in the dataset. Download the dataset as JSON, JSONL, CSV, Excel, HTML table, or XML from the Storage tab, or read it live through the Apify API / apify-client as the run progresses.

Scraped results

[
{
"searchQuery": "realestate",
"postId": "122168152748145259",
"user": {
"name": "Bright Key Realty",
"id": "61554357771285",
"url": "https://www.facebook.com/profile.php?id=61554357771285",
"avatar": "https://scontent.xx.fbcdn.net/v/t39.30808-1/bright-key-avatar.jpg"
},
"url": "https://www.facebook.com/122168152748145259",
"text": "Just listed! 3-bed, 2-bath in Maple Grove — DM us for a private showing. #realestate #maplegrove #newlisting",
"topReactions": { "Like": 214, "Love": 38, "Wow": 4 },
"commentsCount": 19,
"sharesCount": 6,
"videoViewCount": 0,
"time": "2026-06-30 14:12:05",
"timestamp": 1782929525,
"attachments": [
{
"deduplication_key": "0119ac5697c575b62f508b681459152f",
"target": { "__typename": "Photo", "id": "122168152600000001" },
"__typename": "StoryAttachment",
"style_list": ["photo", "fallback"],
"styles": { "__typename": "StoryAttachmentPhotoStyleRenderer" },
"media": { "__typename": "Photo", "id": "122168152600000001" },
"all_subattachments": { "nodes": [] }
}
],
"authorContact": {
"email": "leads@brightkeyrealty.com",
"phone": "+1 555-201-9080",
"website": "https://brightkeyrealty.com",
"instagram": "https://www.instagram.com/brightkeyrealty",
"category": "Real Estate Agent",
"pageLikes": 3120,
"pageFollowers": 3344
},
"isBusinessPage": true,
"hasContact": true
},
{
"searchQuery": "plumber",
"postId": "122168152748145901",
"user": {
"name": "Rapid Flow Plumbing",
"id": "61554357771999",
"url": "https://www.facebook.com/profile.php?id=61554357771999",
"avatar": "https://scontent.xx.fbcdn.net/v/t39.30808-1/rapid-flow-avatar.jpg"
},
"url": "https://www.facebook.com/122168152748145901",
"text": "24-hour emergency callouts across the county. Save our number! #plumber #emergencyplumber",
"topReactions": { "Like": 58, "Care": 3 },
"commentsCount": 4,
"sharesCount": 1,
"videoViewCount": 0,
"time": "2026-06-29 09:47:12",
"timestamp": 1782817632,
"attachments": [],
"authorContact": {
"email": null,
"phone": "+1 555-330-0021",
"website": "https://rapidflowplumbing.com",
"instagram": null,
"category": "Plumbing Service",
"pageLikes": 890,
"pageFollowers": 912
},
"isBusinessPage": true,
"hasContact": true
},
{
"searchQuery": "coffeeshop",
"postId": "122168152748146455",
"user": {
"name": "Alex Rivera",
"id": "61554357772456",
"url": "https://www.facebook.com/profile.php?id=61554357772456",
"avatar": "https://scontent.xx.fbcdn.net/v/t39.30808-1/alex-avatar.jpg"
},
"url": "https://www.facebook.com/122168152748146455",
"text": "Best flat white in town, hands down. #coffeeshop #coffeelover",
"topReactions": { "Like": 12 },
"commentsCount": 2,
"sharesCount": 0,
"videoViewCount": 0,
"time": "2026-06-28 18:03:44",
"timestamp": 1782756224,
"attachments": [],
"authorContact": {
"email": null, "phone": null, "website": null, "instagram": null,
"category": null, "pageLikes": null, "pageFollowers": null
},
"isBusinessPage": false,
"hasContact": false
}
]

If requireContact is off and the run finds no matching posts at all — expired cookies, a locked account, or a genuinely quiet hashtag — the dataset still isn't empty: it carries one clearly labelled diagnostic record instead ({"searchQuery": ..., "postId": "", "text": "<what went wrong>", "status": "credentials_required" | "cookies_expired" | "account_checkpoint" | "no_results", "message": "<what to fix>", ...same base keys as a post row}). This row carries no charged_event_name, so it is never billed — the same is true of every post filtered out by businessPagesOnly or requireContact, which are skipped before push_data is called and so never reach the dataset or the bill.

How can I use the data extracted with this Actor?

  • 🏢 Sales and local-business prospecting: filter the dataset on isBusinessPage: true and hasContact: true, then export authorContact.email / authorContact.phone straight into a CRM or cold-outreach list segmented by the hashtag niche (#realestate, #plumber, #coffeeshop, …).
  • 🤖 AI engineers and LLM developers: an agent issues a hashtag query, receives the structured authorContact + post JSON, and passes it to the model as grounded context for a lead-qualification or outreach-drafting workflow — no scraping code inside the agent itself.
  • 📊 Market researchers: track which businesses are actively posting under a given hashtag, how their topReactions and commentsCount compare, and how many of them expose public contact info (hasContact share-of-total) as a proxy for market formalization in a niche.
  • 🎯 Product and growth teams: identify gaps by comparing authorContact.category distribution across a hashtag's posting businesses — which sub-categories are active on Facebook under a given hashtag and which are under-represented.

📈 How do you monitor business contact leads over time?

Lead monitoring here means re-running the same searchQueries list on a schedule and diffing the resulting leads against the previous run, rather than treating each run as a one-off pull. Because posts under a hashtag turn over continuously, a second run a week later surfaces a mostly-new set of postId values, and each new post is an opportunity for a new lead — or the same Page posting again, which you can dedupe on user.id.

The fields worth diffing between runs:

  • user.id — dedupe across runs to build a running, non-duplicated list of businesses posting under a hashtag, rather than accumulating repeat leads from the same Page.
  • authorContact.hasContact and authorContact.email / authorContact.phone — a Page that had no public contact info last run but does this run is a fresh, actionable lead; alert on that transition specifically.
  • isBusinessPage — track how the ratio of personal-profile posters to business-Page posters shifts for a hashtag over time, useful for gauging how "commercial" a hashtag has become.
  • topReactions / commentsCount / sharesCount on repeat posts from the same author — a rising-engagement signal worth prioritizing in an outreach queue.

Example workflow: schedule a run across your hashtag list every few days → diff the new dataset's user.id values against a stored list of IDs already contacted → push only the net-new hasContact: true rows into your CRM import → alert your sales team on the delta. Set this up with an Apify Schedule pointed at this Actor, and either pull the dataset via the API after each scheduled run or attach a webhook to push new items to your own endpoint as soon as the run finishes.

Integrate the Actor and automate your workflow

The Facebook Hashtag Scraper works with any language or tool that can send an HTTP request — it's a standard Apify Actor reachable through the Apify API, apify-client SDKs, Console schedules, and webhooks.

REST API with Python

import requests
TOKEN = "<YOUR_APIFY_API_TOKEN>"
ACTOR = "<YOUR_USERNAME>/facebook-hashtag-search-scraper-with-business-contact-leads"
url = f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items"
payload = {
"searchQueries": ["realestate", "plumber"],
"maxItems": 25,
"extractContacts": True,
"requireContact": True,
}
headers = {"Authorization": f"Bearer {TOKEN}"}
resp = requests.post(url, json=payload, headers=headers, timeout=300)
leads = resp.json()
for row in leads:
contact = row.get("authorContact", {})
if contact.get("email"):
print(row["user"]["name"], contact["email"])

Scheduled monitoring and delivery

Set up an Apify Schedule in the Console to re-run this Actor against the same hashtag list on a cadence you choose, and attach a webhook to ACTOR.RUN.SUCCEEDED to push each run's dataset to your own endpoint automatically, instead of polling the API for new items.

Yes — this Actor collects only what is already publicly visible to anyone viewing a public hashtag feed or a public Facebook Page, which is generally treated as public data. Courts have distinguished scraping publicly accessible web data from unauthorized computer access — hiQ Labs, Inc. v. LinkedIn Corp., 938 F.3d 985 (9th Cir. 2019) — though that precedent addresses the U.S. Computer Fraud and Abuse Act, not a platform's own Terms of Service, which you remain bound by when you use a login cookie to authenticate. Two different data-protection regimes can apply here: post authors' names and profile IDs can constitute personal data under GDPR/CCPA if the author is an identifiable EU, UK, or California resident, while the business-contact fields (email, phone, website) are details a Page owner has published specifically for customers to make contact, which leans toward a database-rights and ToS framing rather than personal-data protections. Scraping for AI-training datasets and scraping for day-to-day operational lead generation carry different risk profiles. Consult your legal team for commercial use cases involving bulk data storage.

❓ Frequently asked questions

Does the Actor support searching by region or language?

No — the input schema has no locale, region, or language parameter. searchQueries accepts hashtags exactly as Facebook's hashtag feed serves them; there is no built-in localization control.

How do the lead-qualification filters (businessPagesOnly, requireContact) interact?

Both default off, so a base-shaped input returns every post the hashtag feed surfaces, contact info attached where found. Turning on businessPagesOnly drops personal-profile authors before they're pushed; turning on requireContact additionally drops any business Page that exposes neither an email nor a phone. Both filters can be combined, and filtered-out posts are never pushed to the dataset and never charged.

How does the Actor handle Facebook's anti-bot measures?

It pins a single sticky residential proxy IP for the whole authenticated hashtag search (rather than rotating IPs mid-session, which is what tends to trigger account locks), detects Facebook's logged-out page and its account-checkpoint/lock page explicitly, and escalates to a fresh sticky residential session (up to 3 rotations) when a GraphQL response comes back blocked. A locked account is reported immediately rather than retried, since no proxy can recover a checkpointed session. Contact-page lookups, being logged-out, use a separate direct → datacenter → residential escalation ladder.

Does the Actor extract business contact leads for every post?

Yes, when extractContacts is on (the default) — every post's author's public Page is fetched and parsed into the authorContact object described above, with isBusinessPage and hasContact flags alongside it. Contact fields come back null when the author is a personal profile behind a login wall, or a Page that simply hasn't published that field — never fabricated.

How many posts does the Actor return per hashtag?

Up to maxItems (default 10, configurable from 1 to 10000) per hashtag, with each matching post becoming one dataset row. Facebook's own hashtag feed pagination caps out at roughly 200 posts per hashtag, per the input schema's own note, so setting maxItems above that ceiling won't produce more rows than the feed actually contains.

How do I use this Actor to monitor a hashtag's leads over time?

Schedule a run across your hashtag list, dedupe new results against user.id values you've already collected, and alert on posts where authorContact.hasContact newly reads true — see the monitoring section above for the full workflow and the fields to diff.

Does this Actor work with Claude, ChatGPT, and AI agent frameworks?

Yes, as an HTTP endpoint any agent framework can call — an agent issues a run request with a hashtag query, receives the structured post-and-lead JSON back, and generates a grounded answer or outreach draft from it without needing to implement any Facebook-specific scraping logic itself.

How does this Actor compare to other Facebook hashtag scrapers?

As observed on the Apify Store on 2026-07-26: easyapi/facebook-hashtag-search-scraper returns posts (user, text, engagement, attachments) from a single searchQuery string with no bulk hashtag input and no author-contact enrichment — you'd need a second, separate Page-contact tool to get from its output to a lead list. memo23/facebook-pages-and-contacts-scraper goes the other direction: it searches Facebook Pages directly (not hashtags) and returns page details including contact info, but has no hashtag-post entry point at all. This Actor is the only one of the three that starts from a hashtag, returns the post, and returns the author's business contact details in the same row.

Can I use this Actor without managing proxies?

Yes for the network layer — the Actor manages its own proxy escalation (sticky residential for the authenticated search, a direct-to-residential ladder for contact lookups) automatically; you don't configure or rotate anything unless you explicitly want to override it via proxyConfiguration. You do still need to supply your own Facebook login cookies (c_user + xs, or fbCookie) from a healthy, non-locked account — there is no way to run the hashtag-search stage without them.

What happens if my Facebook cookies expire mid-run?

The Actor detects Facebook's logged-out page mid-hashtag and stops that hashtag with a clear cookies_expired diagnostic message rather than looping or burning through the rest of your searchQueries list on a dead session; any hashtags already completed before the cookies expired keep their collected posts.

💬 Your feedback

Found a bug, a field that's coming back null when it shouldn't, or a hashtag format the Actor doesn't parse correctly? Let Scrapier know through the Actor's Issues tab on the Apify Store, or leave a review with details — both are read and used to prioritize fixes.