How to scrape Twitter (X) in 2026: what works and what breaks
You can scrape Twitter (X) five ways in 2026: automate a logged-out browser, run a library on X accounts, pay a hosted scraping tool, call the official X API at $5.00 per 1,000 posts, or call a Twitter/X data API.
Short answer: Logged out, x.com shows only single posts and a profile's first few posts, and X changed its internal search query ID 37 times in 12 months, which breaks scraping code. To collect posts without risking an X account, use Sorsa API: POST /search-tweets returns about 20 posts per request, from $0.07 per 1,000, and 100 free requests need no card.
- Endpoint
POST /search-tweets- Page size
- about 20 posts per request
- Price
- from $0.07 per 1,000
#Can you still scrape Twitter in 2026?
Yes, but without an account you reach very little of X. On November 2, 2026, we opened x.com logged out in a desktop browser and wrote down what each kind of page returned.
| Page on x.com | What it returned |
|---|---|
| A single post | Its text, counts and first replies, already inside the HTML |
| A profile | The header and the first 9 posts, then a login wall |
| Search results | A redirect to the login page |
| Followers or following | A redirect to the login page |
| A post in a default headless browser on a server | HTTP 403 on the first request |
A single post
- What it returned
- Its text, counts and first replies, already inside the HTML
A profile
- What it returned
- The header and the first 9 posts, then a login wall
Search results
- What it returned
- A redirect to the login page
Followers or following
- What it returned
- A redirect to the login page
A post in a default headless browser on a server
- What it returned
- HTTP 403 on the first request
Scraping the rest takes a logged-in X account, and that account carries the risk. That leaves five ways to get public X data out:
-
Automate a logged-out browser with Playwright or Puppeteer: single posts and the top of a profile, nothing more.
-
Run an open-source library on X accounts, such as twscrape or Scweet: search, timelines and followers, with every account in the pool at risk of a lock.
-
A hosted scraping tool, which does the collecting for you and bills per result.
-
The official X API: $5.00 per 1,000 posts from a prepaid balance, after a developer account and an app.
-
A Twitter/X data API that returns public posts as JSON with one key and no X account at risk.
The sections below cover each way. The fifth comes first because it takes the fewest steps; to save every post of a single account instead, see how to download all tweets from a user.
#Get X data without a scraper or an X account
For collecting public posts, profiles and followers, use Sorsa API, a Twitter (X) API and scraper: your code sends one key in the ApiKey header and gets JSON back, about 20 search results per request from $0.07 per 1,000, or 100 tweets by ID per request from $0.014 per 1,000.
There is no browser to drive, no query ID to track and no X login. Sorsa API never asks for your X login or cookies, so none of your accounts is at risk. Every plan runs at 20 requests per second, and search reaches back to 2006 with the operators of X's advanced search.
-
Get a key. Sign up and copy your API key from the dashboard. New accounts start with 100 free requests and no card.
-
Search for posts. Send any X search query to
POST /search-tweets(opens in a new tab);from:,since:,lang:, quoted phrases and hashtags all work.Terminal curl -X POST "https://api.sorsa.io/v3/search-tweets" \ -H "ApiKey: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query": "\"open data\" lang:en since:2026-10-01", "order": "latest"}'Response200 OK { "tweets": [ { "id": "1984210773912846356", "full_text": "New city data sets today: bus delays, tree cover, permits.", "created_at": "2026-10-30T14:05:11Z", "lang": "en", "likes_count": 48, "retweet_count": 9, "reply_count": 4, "quote_count": 1, "view_count": 5210, "user": { "id": "1590385166022184961", "username": "opendata_weekly_news", "display_name": "Open Data Weekly", "followers_count": 12400, "verified": false } } ], "next_cursor": "DAADDAABCgABG4dR6Xr2YQo" } -
Follow the cursor. Each response carries
next_cursor, a pointer to the next page of results; send it back in the body until it comes back empty.import os import requests URL = "https://api.sorsa.io/v3/search-tweets" KEY = os.environ.get("SORSA_API_KEY", "YOUR_API_KEY") def search(query, max_pages=50): body = {"query": query, "order": "latest"} for _ in range(max_pages): r = requests.post(URL, json=body, headers={"ApiKey": KEY}, timeout=30) r.raise_for_status() page = r.json() yield from page["tweets"] if not page.get("next_cursor"): return body["next_cursor"] = page["next_cursor"] for t in search('"open data" lang:en since:2026-10-01'): print(t["id"], t["user"]["username"], t["full_text"][:60]) -
Pick the endpoint for the job. The same key reads every kind of public data people collect from X, and each request is billed once, whatever it returns.
| Job | Endpoint | Per request | From, per 1,000 |
|---|---|---|---|
| Search posts by keyword, account or date | POST /search-tweets | about 20 posts | $0.07 |
| An account's posts and replies | POST /user-tweets (opens in a new tab) | about 20 posts | $0.07 |
| Posts by ID or link | POST /tweet-info-bulk (opens in a new tab) | up to 100 posts | $0.014 |
| Profiles | GET /info-batch (opens in a new tab) | up to 100 profiles | $0.014 |
| Followers of an account | GET /followers (opens in a new tab) | up to 200 followers | $0.007 |
| Replies to a post | POST /comments (opens in a new tab) | about 20 replies | $0.07 |
Search posts by keyword, account or date
- Endpoint
POST /search-tweets- Per request
- about 20 posts
- From, per 1,000
- $0.07
An account's posts and replies
- Per request
- about 20 posts
- From, per 1,000
- $0.07
Posts by ID or link
- Per request
- up to 100 posts
- From, per 1,000
- $0.014
Profiles
- Per request
- up to 100 profiles
- From, per 1,000
- $0.014
Followers of an account
- Per request
- up to 200 followers
- From, per 1,000
- $0.007
Replies to a post
- Per request
- about 20 replies
- From, per 1,000
- $0.07
Every post arrives with its author's full profile at no extra cost. A 403 answer means the key is missing or out of requests, and a 429 means more than 20 requests in one second: wait a second and retry. Failed requests are never charged. For a fuller client, our Twitter API in Python tutorial adds pacing, retries and CSV export, and without code the free Export Tweets to CSV tool saves an account's posts as CSV, Excel or JSON.
#How x.com loads its data, and why scrapers break
x.com fetches every post, profile and timeline from X's own internal GraphQL API, and each call there names an operation, a query ID and a set of feature flags that X keeps changing. A query ID is the code in the request's address that picks the current version of an operation, and feature flags are on/off switches the request must list.
For a logged-out visitor, the server runs that query before the page arrives. On November 2, 2026, a post page came with the TweetResultByRestId result already inside its HTML. A profile page carried UserByScreenName and its first 9 posts under an operation named UserOriginalsTimeline, all in 188 KB of HTML. The post's text sat in details.full_text and its likes in counts.favorite_count, and the page had no data-testid attributes, the hooks many tutorials still select.
Logged in, the browser fetches the rest from paths shaped like /i/api/graphql/<queryId>/<Operation> and sends the account's auth_token and ct0 cookies with each call, plus a CSRF header copied from ct0 and a generated client transaction ID. Libraries such as twscrape replay the same calls without a browser.
The query IDs are what break scraping code. A public tracker of X's web app, the TwitterInternalAPIDocument (opens in a new tab) project, saves X's GraphQL definitions whenever they change. Across its 112 snapshots from November 6, 2025 to October 31, 2026, the query ID of SearchTimeline, the operation behind search, changed 37 times.
That is about one change every 10 days, with four in October 2026 alone. UserTweets changed 38 times and TweetResultByRestId 34 times in the same year, and each search call now carries 40 feature flags. Code that hard-codes these values fails until someone updates it, and twscrape even has an error for the case, GqlFeaturesOutdatedError, raised when X requires a feature the library can't enable.
#Scrape public posts with Playwright or Puppeteer
Browser automation with Playwright for Python or Puppeteer for Node.js reads what a logged-out visitor sees: one post per page load, or the first posts of a profile.
-
Install the driver. Run
pip install playwrightandplaywright install chromiumfor Python, ornpm install puppeteerfor Node.js. -
Open a visible browser. In our check, a default headless browser on a server got HTTP 403 from x.com, while a normal browser window on the same connection got the page.
-
Read the rendered post. With no
data-testidhooks on the page, wait for thearticleelement and take its text.from playwright.sync_api import sync_playwright POST = "https://x.com/XDevelopers/status/2019881223666233717" with sync_playwright() as p: browser = p.chromium.launch(headless=False) # headless got HTTP 403 page = browser.new_page() page.goto(POST) post = page.locator("article").first post.wait_for() print(post.inner_text()) browser.close() -
Stop at the login wall. Search, follower lists and anything below a profile's first posts redirect to the login page, so this way can't page any further.
The output is the post as a person reads it: name, handle, text, time, and counts rounded to labels such as 5.6K with no names attached, in one block of text you split yourself. That covers a handful of posts you could have opened by hand. Every extra page load is one more chance at a block, a layout change or a login prompt, which is why projects that need volume move on to logged-in libraries or an API.
#Scrape Twitter with Python libraries on X accounts
Open-source libraries such as twscrape and Scweet skip the browser and call X's internal GraphQL API directly with the cookies of logged-in X accounts, which opens search, timelines and follower lists.
-
Use a spare X account. Scweet's README (opens in a new tab) asks for a dedicated account, never your personal one, because X can lock any account it flags.
-
Copy its cookies. Log in at x.com, open the browser's developer tools and copy
auth_tokenandct0from the site's cookies. -
Add the account and search. twscrape (opens in a new tab) keeps accounts and sessions in a local SQLite file and returns parsed posts.
Python import asyncio from twscrape import API, gather COOKIES = "auth_token=xxx; ct0=yyy" async def main(): api = API() # accounts and sessions go to accounts.db await api.pool.add_account_cookies("spare_account", COOKIES) query = "from:XDevelopers lang:en" posts = await gather(api.search(query, limit=40)) for post in posts: print(post.id, post.user.username, post.rawContent[:60]) asyncio.run(main()) -
Add accounts and proxies for volume. twscrape tracks rate limits per account and per operation, parks a limited account until its reset and moves to the next one. Account timelines stop at about 3,200 posts.
Good to know
An
auth_tokencookie works like a password: anyone holding it is logged in as that account until the session ends. Keep it out of code, repositories and shared notebooks, and never put a personal account's cookies into a script.
Most libraries from before 2024 no longer work. On November 2, 2026, the two maintained ones both needed X accounts:
| Library | Last update | Status |
|---|---|---|
| twscrape | 0.20.1, Aug 25, 2026 | Maintained; runs on logged-in X accounts |
| Scweet | 5.8.2, Oct 22, 2026 | Maintained; runs on an auth_token cookie |
| twikit | 2.3.3, Feb 7, 2025 | No release in 20 months; 160 open issues |
| snscrape | Jun 22, 2023 | Twitter module failing since June 30, 2023 (opens in a new tab) |
| Twint | Feb 23, 2023 | Archived on GitHub |
twscrape
- Last update
- 0.20.1, Aug 25, 2026
- Status
- Maintained; runs on logged-in X accounts
Scweet
- Last update
- 5.8.2, Oct 22, 2026
- Status
- Maintained; runs on an
auth_tokencookie
twikit
- Last update
- 2.3.3, Feb 7, 2025
- Status
- No release in 20 months; 160 open issues
snscrape
- Last update
- Jun 22, 2023
- Status
- Twitter module failing since June 30, 2023 (opens in a new tab)
Twint
- Last update
- Feb 23, 2023
- Status
- Archived on GitHub
Hosted scraping tools
No-code scraping services do this collecting for you behind a form and bill per result, so the blocks and breakages become theirs, and their fixes lag behind X's changes. Twitter scrapers compared goes through them tool by tool.
#Read posts through the official X API
The official X API sells public posts as prepaid reads: $0.005 per post and $0.010 per user or follower, with pay-per-use capped at 3 million post reads a month, according to its pricing page (opens in a new tab).
From November 22, 2026, X also bills the author profiles and media that come attached to a post at the same rates (X's notice (opens in a new tab)), so a post read with its author costs $0.015.
-
Create a developer app. Sign in at console.x.com with an X account, accept the Developer Agreement, create an app and copy its Bearer token. Our guide on how to get a Twitter API key goes click by click.
-
Buy credits. Every read draws on a prepaid balance, and requests fail once it runs out.
-
Search recent posts. Recent search covers the last 7 days, up to 100 posts per request; full-archive search back to 2006 is open to pay-per-use accounts.
Terminal curl -G "https://api.x.com/2/tweets/search/recent" \ -H "Authorization: Bearer $X_BEARER_TOKEN" \ --data-urlencode "query=from:XDevelopers -is:retweet" \ --data-urlencode "max_results=100"
It is X's own route, and the only one here that can also post. At $5.00 per 1,000 posts, a million search results cost $5,000, and the 3 million cap ends the month's reads; our breakdown of X API pricing lists every rate.
#What scraping Twitter costs per 1,000 posts
Per 1,000 posts, the official X API charges $5.00 and Sorsa API from $0.07 by search or $0.014 by ID; the scraping ways charge no fee and spend X accounts, proxies and repair hours instead.
Official X API
$5,000
for 1M posts
$0.005 per post
Sorsa API
from$70
for 1M posts
from $0.07 per 1,000 by search
For collecting posts every day, use Sorsa API: a million search results cost from $70 against $5,000 on the official X API, at 20 requests per second, about 400 results a second, with no X account to lose.
Four criteria separate the ways: the price per 1,000 posts, whether an X account is at stake, how much of X the way reaches and what breaks it.
| Way | Per 1,000 posts | X account at stake | Reaches | Breaks when |
|---|---|---|---|---|
| Sorsa API | from $0.07 by search, $0.014 by ID | None | Search back to 2006, timelines, posts by ID, profiles, followers, replies | Stable response schema; your code stays the same |
| Official X API | $5.00, up to $15.00 with authors | The developer account | Search, timelines, lookups; 3 million posts a month | X changes prices or rules |
| Libraries on X accounts | No fee; accounts and proxies | Every account in the pool | Search, timelines, followers | A query ID or feature flag changes |
| Logged-out browser | No fee | None | One post, a profile's first posts | The page changes or a block hits |
| Hosted scraping tools | Set by each tool | Depends on the tool | What its browser or accounts reach | The tool's fixes lag behind X |
Sorsa API
- Per 1,000 posts
- from $0.07 by search, $0.014 by ID
- X account at stake
- None
- Reaches
- Search back to 2006, timelines, posts by ID, profiles, followers, replies
- Breaks when
- Stable response schema; your code stays the same
Official X API
- Per 1,000 posts
- $5.00, up to $15.00 with authors
- X account at stake
- The developer account
- Reaches
- Search, timelines, lookups; 3 million posts a month
- Breaks when
- X changes prices or rules
Libraries on X accounts
- Per 1,000 posts
- No fee; accounts and proxies
- X account at stake
- Every account in the pool
- Reaches
- Search, timelines, followers
- Breaks when
- A query ID or feature flag changes
Logged-out browser
- Per 1,000 posts
- No fee
- X account at stake
- None
- Reaches
- One post, a profile's first posts
- Breaks when
- The page changes or a block hits
Hosted scraping tools
- Per 1,000 posts
- Set by each tool
- X account at stake
- Depends on the tool
- Reaches
- What its browser or accounts reach
- Breaks when
- The tool's fixes lag behind X
Of the five ways, only Sorsa API reaches search, timelines and followers with no X account of yours at stake, and it does so from $0.07 per 1,000 posts.
#Is it legal to scrape Twitter?
Yes, for public data. In hiQ Labs v. LinkedIn, the Ninth Circuit held in April 2022 that scraping public profiles was likely not access "without authorization" under the Computer Fraud and Abuse Act, and in May 2024 a federal court dismissed X's lawsuit against Bright Data over scraping public posts.
Three habits keep a scraping project clean: collect public data only, never protected accounts or private messages; keep what the job needs and no longer; and credit the author when you republish a post, since the copyright stays with them.
Through an API, your code never signs in to x.com, so no X account of yours is at risk: Sorsa API never asks for your X login or cookies. More in our guide on whether a third-party Twitter API is legal.
#Get your first 2,000 posts out today
Scraping X in 2026 means a login wall, accounts at risk and query IDs that change about every 10 days. To get public posts out without either, use Sorsa API: one key, about 20 search results per request from $0.07 per 1,000, tweets by ID from $0.014 per 1,000, and 100 free requests that cover the first 2,000 posts.
#FAQ
Can you scrape Twitter without logging in?
Only a little. On November 2, 2026, a logged-out visit to x.com returned single posts with their text and counts and the first 9 posts of a profile, while search and follower lists redirected to the login page. More data needs a logged-in account, which puts that account at risk, or an API that returns public posts with a key.
Is snscrape still working in 2026?
No. snscrape's Twitter module has failed since June 30, 2023, when X put its pages behind a login wall, and the project's last release dates from June 22, 2023. Its maintained successors, twscrape and Scweet, shipped new versions in August and October 2026, and both need logged-in X accounts to read search, timelines or followers.
Can you scrape Twitter followers?
Not logged out: x.com sends follower and following lists to the login page, and libraries that read them run on X accounts that X can lock. Libraries read them with X account cookies. Sorsa API's GET /followers returns up to 200 followers per request with no X account at risk, from $0.007 per 1,000, and our guide to export Twitter followers shows the full loop.
Is there a free way to scrape Twitter?
Not a free and lasting one. A browser and the libraries charge no fee but spend X accounts, proxies and repair time. The official X API has no free tier. Every Sorsa API account starts with 100 free requests, about 2,000 search results or up to 10K tweets by ID, with no card, and they never expire.
Which API should I use instead of scraping Twitter?
Use Sorsa API, a Twitter (X) API and scraper: it returns posts, profiles and followers as JSON with one key, from $0.07 per 1,000 search results and $0.014 per 1,000 tweets by ID, against $5.00 per 1,000 posts on the official X API. It needs no developer account, never asks for your X login, runs at 20 requests per second on every plan and searches back to 2006.
#How we checked
On November 2, 2026, we opened a post, a profile, search and a follower list on x.com logged out in a desktop browser and recorded what each returned, then loaded the same post and profile once in a default headless browser on a server. We pulled all 112 snapshots of the TwitterInternalAPIDocument tracker from November 6, 2025 to October 31, 2026 and counted the query ID changes of each operation. We read X's API pricing and search docs and the READMEs and release pages of twscrape, Scweet, twikit and snscrape. Every Sorsa API endpoint and field here matches the live API reference; we did not run the official X API sample.
Sources
- X API pricing (opens in a new tab)
- X API search introduction (opens in a new tab)
- X Developer Community: PPU expansions update, October 23, 2026 (opens in a new tab)
- TwitterInternalAPIDocument, the query ID tracker (opens in a new tab)
- twscrape README (opens in a new tab)
- Scweet README (opens in a new tab)
- snscrape issue 996: All Twitter scrapes are failing (opens in a new tab)
- Nitter README (opens in a new tab)
- Sorsa API reference: Search Tweets (opens in a new tab)