Guide, measured 2026-11-10
How to scrape Threads, and where the login prompt really stops you
Threads shows public profiles and posts to anyone, then asks for a login after the first few. What the interface hides and what the server refuses are two different lines. Here is what a logged-out visitor is served, surface by surface, what stops at the login prompt, what Meta's official Threads API offers instead and when it is the better choice, with our measurements and their limits.
What Threads shows a visitor without an account
Open a public profile in a browser where nobody is signed in. The page loads, shows the account's first posts, and its text ends with "Log in to see more from" the account, under a window that offers to continue with Instagram. We scrolled such a page four times in a fresh headless Chromium on 2026-11-10: the interface made no request for a next page of posts. As far as the screen goes, a profile is its first posts.
A single post opens the same way, with the first replies under it. A keyword search shows one set of results. That is the whole logged-out interface.
The page carries its data, and a cursor
A browser is not needed to read that page. A plain HTTP request for the profile URL, sent with the headers a browser sends when it opens a page, gets the same HTML, and the posts are in it as JSON:
GET https://www.threads.com/@nasa
with the headers a browser sends when it opens a page (accept, sec-fetch-*)
-> HTTP 200, about 1.09 MB of HTML (about 199 KB on the wire), holding as JSON:
the profile: follower count, bio, links
the first posts
page_info: { has_next_page: true, end_cursor: "..." }
the page's token ("LSD") and the app id the page's own requests sendTwo details matter. A request that sends only a user agent gets an empty shell, which is why Threads is often said to need a browser: an earlier probe of ours made that mistake. With ordinary navigation headers, plain curl received the full page; which header makes the difference, we did not isolate. And the page says who is asking: its own data gives the current user as 0, and marks the session as logged out.
The cursor is the interesting part. The interface never uses it for a logged-out visitor, but the server puts it in the page it serves that visitor.
The next page answers, up to about 200 posts
The Threads web page loads more posts through one GraphQL request. Sent with that cursor, and with nothing a logged-out page does not have, it is answered:
POST https://www.threads.com/api/graphql
the page's token, the app id header the page publishes,
the two anonymous cookies the first GET set (no session, no account)
doc_id = the id of the page's own next-page operation
variables = what the page preloaded for that tab, plus after = end_cursor, first = 25
-> JSON: the next threads, and a new page_info with the next cursorFrom one home connection on 2026-11-10, this reached 201 posts of @natgeo in 19 requests and 200 posts of @nasa in 7 requests and 17 seconds, every answer HTTP 200. A page of 25 returns 25 threads, and a thread can hold several posts by its author, so it came to about 33 posts a request. Each post weighs about 20 KB of JSON before compression.
Then it ends. From Apify's cloud the same day, a profile asked for 1,000 posts gave 208 and Threads closed the list (run pmo2BqGmFrha0Yq9s); another gave 222, then an error from Threads on its 11th page (run hh3DEngH0uabFN8r6). So the logged-out depth of a profile is about 200 posts, the newest ones. One day and two profiles: the exact number may differ per profile.
One trap: the id of the next-page operation (doc_id) is not in the page. It is defined in the page's script bundles, and Meta changes those at will. On the two pages we checked, the page listed the 17 bundles it loads itself and both operations were among them, so a reader can find the id at run time instead of hard-coding it. A reader that hard-codes it will break one day without warning.
Where the login wall holds, surface by surface
The depth is not the same everywhere. Profiles and replies are paginated for a logged-out session; search is not, and that is where the wall holds at the level of the data, not only of the interface.
| Surface | What a logged-out request gets |
|---|---|
| A public profile's posts | First posts in the page, then a next page for each cursor, up to about 200 posts: 208 on the one profile read to its end. The newest first; the rest of the history is not served. |
| A single post, by its URL | In the page, with the first replies. |
| Replies under a post | Paginated like a profile. 300 replies read under one post, with more to come; where the list ends was not measured. |
| Keyword search | About 20 posts (18 to 24 in our runs), and no cursor. Asking again returns a partly different sample: 30 distinct posts after two requests in our test. |
| An account's Replies tab | 25 reply threads, then nothing: no cursor, whatever the size asked. |
| View counts | Not sent. No page or answer we read carried one. |
| Private profiles | No posts for a logged-out visitor. |
Search is the honest weak point of any logged-out approach. A keyword gives about 20 posts, there is no second page to ask for, and asking again only reshuffles the sample. If you need every post that mentions a term, the logged-out web does not have it. If you need what given accounts post, and what people answer under given posts, it does.
Not probed by us: account search, tag search, and the Reposts and Media tabs of a profile.
What it looked like from the cloud
The measurements above were first made from one home connection. From Apify's datacenter addresses on 2026-11-10, with a private build of our Actor, plain HTTP in 256 MB of memory: 400 posts from two profiles in 73 seconds and 16 requests (run Sbx7WfBTCfE6qXJOa); one post and 300 replies in 55 seconds (run Wd2ibCEoiT8m2lFiB); five searches in 37 seconds, 105 posts (run JR19qCm2PSMihZ3LZ). In the four runs of the current build, none of 70 requests was refused.
That is a handful of runs on one day, not a success rate. What was not measured: many runs over days, the pace Threads accepts from several sessions at once, and how often the operation ids change. One search of an earlier build timed out and was lost; a request without an answer is now sent once more, from a fresh session, and never after an answer.
The official Threads API, and when it fits
Meta has an official API for Threads, and for some jobs it is the right tool. What follows is from its documentation as we read it on 2026-11-10; we have not used it, and Meta can change it.
- It works for an account that authorizes your app. A user grants your app permissions in an authorization window, and your app gets an access token; the
threads_basicpermission is required for every call (Get Access Tokens). - Your own posts and their numbers. It lists the posts of the authorizing account (Retrieve User Posts), and its insights endpoints give that account's likes, replies, reposts and quotes, and views, a metric the page marks as in development (Insights). Views are exactly what a logged-out page does not carry.
- Other accounts' public posts, with a permission. A
profile_postsendpoint returns a public profile's posts by username. It needs thethreads_profile_discoverypermission, returns only profiles with at least 100 followers, and allows a user 1,000 requests per rolling 24 hours. With standard access, only a few official Meta accounts can be read (Retrieve User Posts). - Keyword search, after approval. The search endpoint needs the
threads_keyword_searchpermission. Until Meta approves it for your app, a search covers only the posts of the authenticated user; after approval, public posts. A user can send 2,200 queries per rolling 24 hours, and the owner field is not returned (Keyword Search).
So the official API fits when you manage the accounts in question (publishing, replies, your own analytics with views), and when you build a product that can go through Meta's approval for public search and profile discovery: it is the route Meta permits, with documented limits and no page that changes under you. It fits less when you need other accounts' public posts today and have no approved app, which is the case the logged-out web covers, at about 200 posts per profile and without views.
Or use our Actor
Our Threads scraper is one way to do the logged-out part: profiles, post URLs with their replies and keyword searches in one run, the operation ids read from the page at run time, one row per post, a free row per profile, and a summary that says where each list stopped and why. It never uses an account, a cookie from a signed-in session or the official API, and when Threads refuses a request it stops reading that source.
It costs $1.50 per 1,000 posts or replies ($1.35 on Apify's Silver plan, $1.20 on Gold and up), with no start fee. Profile rows, sources not found or failed, and duplicates are free. It is built and measured, and coming to the Apify Store: it is not listed yet.
The lines we keep
- Logged out, always. No account, no cookie from a signed-in session, no borrowed session of yours. Whatever needs one is out of scope.
- Never past a refusal. A refusal from Threads ends the source, and the run says so. Nothing is retried after an answer.
- Public posts of public profiles. Private profiles serve nothing logged out. Posts are written by people: what you store and how you use it, under privacy law such as the GDPR, is your responsibility.
- What Meta says. Meta's terms prohibit automated collection without its permission, and Threads' robots.txt said, when we read it on 2026-10-05: "Collection of data on Threads through automated means is prohibited unless you have express written permission". The interface asks a visitor to log in after a profile's first posts, while the server answers the next page for a session it knows is logged out. Weigh that for your own use; the official API above is the route Meta permits.
The same question, what a Meta page serves logged out and where it stops, for ads: how to scrape the Facebook Ad Library.
Questions
Can you scrape Threads without logging in?
Yes, within limits. A public profile's page, fetched logged out, carries its first posts, and Threads answers the page's own next-page request for a logged-out session up to about 200 posts (208 on the one profile we read to its end, 2026-11-10). Replies under a post are served the same way. Search gives about 20 posts per query and no further page.
Why does Threads say "Log in to see more"?
In a browser without an account, a profile shows its first posts, then "Log in to see more from" the account, under a sign-in window. The interface never asks for the next page. The page it loaded does carry a cursor for that next page, and the server answers it for a logged-out session, up to about 200 posts.
How many posts can you get from a Threads profile without an account?
About 200, the newest. In our cloud runs of 2026-11-10, one profile asked for 1,000 posts gave 208 and Threads ended the list; another gave 222 before Threads answered an error. Older posts are not served to a logged-out visitor.
Is there an official Threads API for public posts?
Yes, with conditions. Per Meta's documentation read on 2026-11-10, every call needs an access token from a user who authorized your app. Another account's public posts need the threads_profile_discovery permission (profiles of at least 100 followers; with standard access, only a few official Meta accounts), and keyword search covers public posts only after Meta approves the threads_keyword_search permission for your app.
Can you get view counts from Threads?
Not logged out: no page or answer we read on 2026-11-10 carried a post's view count. Meta's official API lists views among the insights of an account's own posts, for an app that account authorized.
Public posts of public profiles only: no login, no account, no cookies. Not affiliated with Meta or Threads.