Threads Scraper - Public Profiles & Post URLs
Pricing
from $2.40 / 1,000 records
Threads Scraper - Public Profiles & Post URLs
Extract public Threads profiles, recent visible posts and exact post URLs with full text, dates, engagement counts, identity checks and duplicate removal.
Pricing
from $2.40 / 1,000 records
Rating
0.0
(0)
Developer
Ben
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
5 days ago
Last modified
Categories
Share
Threads Scraper: public profiles and post URLs
Read public Threads profiles, recent posts visible on profile pages, or a list of exact public post URLs. Export full source text, publication dates, engagement counts, media URLs and stable IDs to JSON, CSV or Excel.
The public Threads profile currently exposes a short preview before asking visitors to log in. This Actor reads that preview. It does not claim full timeline history, keyword search, follower lists, complete replies or authenticated content. Specific post URLs let you inspect older public posts when you already know their URLs.
Choose preview or exact-post extraction: profile pages expose a limited public preview; use known post URLs for specific older posts. Free-plan result events cost $3 per 1,000 records, plus the start event. A higher limit does not unlock a complete timeline.
Quick start
Start with a tested example for public Threads posts:
Open the example and choose Try for free to copy its input into your account. Check the input and set a maximum run charge before starting; Actor fees still follow the pricing below. When the run finishes, open the run's dataset and select the Overview view and download JSON for nested fields or CSV/Excel for a table.
| Your goal | Input to use |
|---|---|
| Recent visible posts | mode: posts with usernames |
| Account snapshots | mode: profiles with usernames |
| A known public post | postUrls in posts mode |
The real output example shows the record shape. The Python workflow saves your own export to a local JSON file with a $0.10 maximum Actor charge.
Supported inputs
| Field | Behavior |
|---|---|
mode | posts by default; profiles returns account metadata. |
usernames | Up to 20 usernames, such as meta or nasa. The default is meta. |
postUrls | Up to 50 exact HTTPS Threads post URLs. These override usernames, including the default username. Requires posts mode. |
postedAfter, postedBefore | Optional inclusive UTC dates in YYYY-MM-DD format. Filter only posts actually exposed on the requested public page. |
maxResults | Maximum exported records across the run, between 1 and 200. It cannot expand the source's public preview. |
To collect recent public posts from two organizational accounts:
{"mode": "posts","usernames": ["meta","nasa"],"maxResults": 10}
To read a known public post without adding the default account's recent posts:
{"mode":"posts","postUrls":["https://www.threads.com/@meta/post/Dc4G-rQE17m"],"maxResults":1}
Choose profiles mode for account IDs, names, biographies and follower counts. Date filters are rejected in that mode because an account snapshot is not a dated post. No login cookies, account password or third-party data API key is required.
Example output
One complete record from a verified September 9, 2026 cloud run. Values and public media URLs can change or expire; this is a dated sample.
{"record_type": "post","id": "3978960966109060838","url": "https://www.threads.com/@meta/post/Dc4G-rQE17m","username": "meta","author_id": "63053551787","full_name": "Meta","is_verified": true,"text": "brb, cloud watching while my meta glasses play the perfect soundtrack","posted_at": "2026-09-04T19:12:11+00:00","likes": 278,"replies": 91,"reposts": 25,"quotes": 0,"is_reply": false,"reply_to_author": null,"image_urls": [],"video_urls": [],"scraped_at": "2026-09-09T20:11:06.166199+00:00"}
Output and identity checks
Every row contains record_type, id, url, username and scraped_at. Post rows include the complete caption supplied by the source, posted_at in UTC, author ID, likes, replies, reposts, quotes, reply status and exposed image/video URLs. Profile rows include the public biography, follower count, full name and verification status.
Optional fields remain null when unavailable. A zero count is preserved as zero. A missing count is never converted to zero. Profile and post records have different fields; use record_type when loading a mixed dataset into your database.
The parser checks the page's canonical identity when available, filters records to the requested author and, for exact URLs, requires the requested post code. Replies from other accounts are not exported as posts by the requested account. Duplicate post IDs are removed across pages and overlapping inputs. A profile's own visible replies can appear in its public preview and retain their reply flag.
The Meta post in the example supplied the text “brb, cloud watching while my meta glasses play the perfect soundtrack” during local verification on September 9, 2026. This is an example of actual source output, not a promise that engagement counts or public availability will remain unchanged.
Coverage and failures
The Output tab exposes the dataset and SUMMARY. The summary reports pages read, source records, filtered records, duplicate IDs, actual exports and the stop reason. coverage_complete remains false: a successful public preview is not a complete account history or all replies to a post.
Dates restrict this visible window. If every exposed post falls outside the dates, a successful run can return zero records. If the page supplies no usable requested records, the Actor fails explicitly instead of reporting a successful empty scrape. A removed post, private account or login requirement may cause that error.
Media URLs may expire. The Actor exports their public URLs and does not download media files. Counts and text reflect the source at observation time. Changes between runs are expected. Retain the stable post ID as your downstream key when comparing exports or importing a scheduled feed.
Pricing and recurring use
The Free price is $0.003 per exported record plus a $0.00005 start event at the default 512 MB. Ten records cost $0.03005 before plan discounts. Per 1,000 records, Bronze is $2.70, Silver $2.55, and Gold, Platinum and Diamond are $2.40 at the currently saved rates. Start costs $0.000045 on Bronze, $0.0000425 on Silver and $0.000040 on Gold or higher. The Store pricing panel and actual run usage are authoritative.
Only exported records create result events. Source-filtered and duplicate records are not billed as results. The Actor respects Apify's maximum charge control and records a spending-limit stop in its summary. Failed runs can leave a partial dataset, so reconcile repeated imports by stable ID.
Use a saved Task with a fixed organizational-account list for repeat observations, or supply exact URLs from your existing research workflow. An API client, n8n, Make or Zapier can read the resulting dataset. This version does not maintain persistent only-new state; deduplicate repeated runs in the receiving system.
Python API workflow
Copy the first input JSON above into input.json and save this code as export.py. In a Python virtual environment, install apify-client with python -m pip install apify-client. Set APIFY_TOKEN to your own Apify token in your environment, then run python export.py. Keep the token out of source files and shared screenshots.
import jsonimport osfrom decimal import Decimalfrom pathlib import Pathfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("benthepythondev/threads-public-scraper").call(run_input=json.loads(Path("input.json").read_text(encoding="utf-8")),max_total_charge_usd=Decimal("0.10"),memory_mbytes=512,timeout_secs=300,)if not run or run["status"] != "SUCCEEDED":raise RuntimeError(f"Inspect the run before retrying: {run and run['id']}")rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())Path("threads-posts.json").write_text(json.dumps(rows, ensure_ascii=False, indent=2), encoding="utf-8")print(f"Saved {len(rows)} records from run {run['id']}")
This starts a run in your account, waits for completion and saves threads-posts.json. The $0.10 limit bounds Actor charges; it is not a promised bill or result count. Check the printed run ID and server log if the result is shorter than expected. If your client loses its connection, inspect the existing run in Console before starting another one. See the official Python client for other run options.
Keep id as the import key. For an observation history, also retain scraped_at; for a current-post table, upsert by ID. Scheduling repeats the public preview and does not expand it into a full account history.
For recurring runs without writing a scheduler, copy a tested public Task into your account and attach an Apify Schedule to that copy. Keep its maximum-charge limit and avoid overlapping runs when using monitor state. The Python example above is also suitable for an existing scheduler; run it from the directory containing input.json and provide the token through that scheduler's secret settings.
Questions
Can it export an entire account history? No. Logged-out profile pages expose only their public preview. Known public post URLs are supported separately.
Does a successful zero-result date filter mean the account posted nothing? No. It means none of the scanned public preview records matched those bounds.
Can I search Threads globally? This version accepts usernames and exact post URLs. It does not advertise global search.
Can I reuse media or personal information freely? Public visibility does not remove applicable data protection obligations or copyright restrictions.
Related tools
Instagram provides public profile and timeline observations with date filters. Meta Ad Library supports advertiser-specific creative monitoring, while Facebook Pages exports public organizational Page information.
Keywords: Threads public scraper, Threads profile data, public posts, exact post URLs, full captions, publication dates, engagement counts, account snapshots, CSV export, research feeds.