snscrape, Twint, twikit and twscrape: what still works on X
snscrape and Twint stopped working for X in 2023 and will not return, twikit's last release has failed since X's change of March 18, 2026, and twscrape still works, but only on logged-in X accounts that you supply.
Short answer: On November 2, 2026, snscrape still returns blocked (404) for X, as it has since June 30, 2023, Twint is archived, and twikit 2.3.3 dates from February 2025. To run the same jobs without risking an X account, use Sorsa API: POST /search-tweets takes your old query, about 20 tweets per request from $0.07 per 1,000, with 100 free requests.
- Endpoint
POST /search-tweets- Page size
- about 20 tweets per request
- Price
- from $0.07 per 1,000
#Which Twitter scraping libraries still work in 2026
Of the eight Python libraries people still install for X data, two are maintained and working, one works as a fork, one updates slowly, and four are dead or broken. Every library that still works logs in as an X account, because X has shown search, full timelines and follower lists only to logged-in users since June 30, 2023.
The table holds what PyPI and GitHub showed on November 2, 2026, with the error each library prints when it fails.
| Library | Last release | Status | Needs | Error you see |
|---|---|---|---|---|
| snscrape | Jun 22, 2023 | Twitter module dead | Nothing (logged out) | blocked (404) |
| Twint | Apr 29, 2020 | Archived Mar 30, 2023 | Nothing (logged out) | Guest token not found |
| twikit | Feb 7, 2025 | Broken since Mar 18, 2026 | Login or cookies | KEY_BYTE indices |
| twifork | Aug 30, 2026 | Working fork of twikit | Browser cookies | Stale cookies |
| twscrape | Aug 25, 2026 | Working | X accounts | Account locks, 403 |
| Scweet | Oct 22, 2026 | Working | An auth_token cookie | Account locks |
| ntscraper | May 24, 2025 | Dead with Nitter | A Nitter instance | Instances down |
| tweety | Jul 15, 2025 | Slow updates | An X account | Account turns read-only |
snscrape
- Last release
- Jun 22, 2023
- Status
- Twitter module dead
- Needs
- Nothing (logged out)
- Error you see
blocked (404)
Twint
- Last release
- Apr 29, 2020
- Status
- Archived Mar 30, 2023
- Needs
- Nothing (logged out)
- Error you see
- Guest token not found
twikit
- Last release
- Feb 7, 2025
- Status
- Broken since Mar 18, 2026
- Needs
- Login or cookies
- Error you see
KEY_BYTE indices
twifork
- Last release
- Aug 30, 2026
- Status
- Working fork of twikit
- Needs
- Browser cookies
- Error you see
- Stale cookies
twscrape
- Last release
- Aug 25, 2026
- Status
- Working
- Needs
- X accounts
- Error you see
- Account locks, 403
Scweet
- Last release
- Oct 22, 2026
- Status
- Working
- Needs
- An
auth_tokencookie - Error you see
- Account locks
ntscraper
- Last release
- May 24, 2025
- Status
- Dead with Nitter
- Needs
- A Nitter instance
- Error you see
- Instances down
tweety
- Last release
- Jul 15, 2025
- Status
- Slow updates
- Needs
- An X account
- Error you see
- Account turns read-only
Two patterns explain the whole table. The libraries that read X logged out (snscrape, Twint, ntscraper through Nitter) lost their data source, and no patch brings it back. The ones that log in keep working only while their X accounts stay active and their code keeps pace with X's web app, which changed its internal search query ID 37 times in the last 12 months. Our guide on how to scrape Twitter covers browsers and the official X API as well.
#Replace a library call with one Sorsa API request
For a project that used any of these libraries, use Sorsa API, a Twitter (X) API and scraper: it returns the same public tweets, profiles and follower lists as JSON from one ApiKey header, with no X account, cookies or proxies, and when X changes its web app the fix happens on our side while your code and the response schema stay the same. Search results cost from $0.07 per 1,000, followers from $0.007 per 1,000, and every plan, the free start included, allows 20 requests per second.
Four steps move a script over:
-
Get a key. Sign up and copy the API key from the dashboard. The first 100 requests are free and never expire.
-
Add one helper. These functions replace the library import. Each list endpoint returns a page and a
next_cursor; the helper sends the cursor back until it comes back empty.sorsa_helper.py import requests BASE = "https://api.sorsa.io/v3" HEADERS = {"ApiKey": "YOUR_API_KEY"} def pages(method, path, payload): """Call a Sorsa API list endpoint and yield every page.""" payload = dict(payload) send = requests.get if method == "GET" else requests.post arg = "params" if method == "GET" else "json" while True: r = send(BASE + path, headers=HEADERS, timeout=30, **{arg: payload}) r.raise_for_status() # 403: key or quota, 429: over 20 requests/s page = r.json() yield page if not page.get("next_cursor"): return payload["next_cursor"] = page["next_cursor"] def items(method, path, payload, key, limit=None): """Yield tweets or users across pages, stopping at limit.""" n = 0 for page in pages(method, path, payload): for item in page.get(key) or []: yield item n += 1 if limit and n >= limit: return def search(query, limit=None, order="latest"): body = {"query": query, "order": order} return items("POST", "/search-tweets", body, "tweets", limit) def user_tweets(username, limit=None): body = {"username": username} return items("POST", "/user-tweets", body, "tweets", limit) def followers(username, limit=None): params = {"username": username} return items("GET", "/followers", params, "users", limit) -
Swap each call. Pick your library and the call your script makes; the converter shows the matching request.
Your libraryBefore: snscrapescraper = sntwitter.TwitterSearchScraper( "python lang:en") for tweet in scraper.get_items(): print(tweet.rawContent)After: Sorsa APIfor tweet in search("python lang:en"): print(tweet["full_text"])- Endpoint
POST /search-tweets- One request returns
- about 20 tweets
- Price on Sorsa API
- from $0.07 per 1,000 tweets
Your query string moves over as it is:
from:,since:,until:,lang:andmin_faves:work the same. Setorderto"latest"for snscrape's newest-first order.Each library call maps to one Sorsa API endpoint. Writing calls and likes have no read-only equivalent.
-
Check the first page. Every response carries the full author profile inside each tweet, so the second lookup that twscrape and twikit need for a user ID goes away.
Response200 OK { "tweets": [ { "id": "2116173807613027825", "full_text": "Moved our nightly tweet pull off a dead library.", "created_at": "2026-10-30T14:22:07Z", "lang": "en", "likes_count": 214, "retweet_count": 37, "reply_count": 19, "quote_count": 6, "view_count": 18450, "conversation_id_str": "2116173807613027825", "user": { "id": "1592041833471827968", "username": "lena_ships_python", "display_name": "Lena Ships Python", "followers_count": 2310 } } ], "next_cursor": "DAACCgACGW7xDmNAJxAKAAMZbvEOY0AnEAgABAAAAAEAAA" }
The full call map
The tables cover the calls that most scripts make. Each row is one Sorsa API request; the library columns give the call it replaces. The logged-in libraries come first, since their scripts are the ones still running.
| Job | Sorsa API | twikit | twscrape |
|---|---|---|---|
| Search tweets | POST /search-tweets (opens in a new tab) | search_tweet | search |
| A user's tweets | POST /user-tweets (opens in a new tab) | get_user_tweets | user_tweets |
| One profile | GET /info (opens in a new tab) | get_user_by_screen_name | user_by_login |
| Followers | GET /followers (opens in a new tab) | get_user_followers | followers |
| Following | GET /follows (opens in a new tab) | get_user_following | following |
| One tweet | POST /tweet-info (opens in a new tab) | get_tweet_by_id | tweet_details |
| 100 tweets by ID | POST /tweet-info-bulk (opens in a new tab) | get_tweets_by_ids | none |
| Replies to a tweet | POST /comments (opens in a new tab) | get_tweet_by_id | tweet_replies |
| Retweeters | POST /retweeters (opens in a new tab) | get_retweeters | retweeters |
| Search users | POST /search-users (opens in a new tab) | search_user | search_user |
| List tweets | GET /list-tweets (opens in a new tab) | get_list_tweets | list_timeline |
| Trends | GET /trends (opens in a new tab) | get_place_trends | trends |
| Account "About" data | GET /about (opens in a new tab) | none | user_about |
Search tweets
- twikit
- search_tweet
- twscrape
- search
A user's tweets
- twikit
- get_user_tweets
- twscrape
- user_tweets
One profile
- Sorsa API
- GET /info (opens in a new tab)
- twikit
- get_user_by_screen_name
- twscrape
- user_by_login
Followers
- Sorsa API
- GET /followers (opens in a new tab)
- twikit
- get_user_followers
- twscrape
- followers
Following
- Sorsa API
- GET /follows (opens in a new tab)
- twikit
- get_user_following
- twscrape
- following
One tweet
- twikit
- get_tweet_by_id
- twscrape
- tweet_details
100 tweets by ID
- twikit
- get_tweets_by_ids
- twscrape
- none
Replies to a tweet
- Sorsa API
- POST /comments (opens in a new tab)
- twikit
- get_tweet_by_id
- twscrape
- tweet_replies
Retweeters
- twikit
- get_retweeters
- twscrape
- retweeters
Search users
- twikit
- search_user
- twscrape
- search_user
List tweets
- twikit
- get_list_tweets
- twscrape
- list_timeline
Trends
- Sorsa API
- GET /trends (opens in a new tab)
- twikit
- get_place_trends
- twscrape
- trends
Account "About" data
- Sorsa API
- GET /about (opens in a new tab)
- twikit
- none
- twscrape
- user_about
snscrape and Twint covered fewer jobs, and each one maps to the same endpoints:
| Job | Sorsa API | snscrape | Twint |
|---|---|---|---|
| Search tweets | POST /search-tweets | TwitterSearchScraper | run.Search |
| Hashtag | POST /search-tweets | TwitterHashtagScraper | c.Search with #tag |
| A user's tweets | POST /user-tweets | TwitterUserScraper | c.Username |
| One profile | GET /info | TwitterUserScraper.entity | run.Lookup |
| Followers | GET /followers | none | run.Followers |
| Following | GET /follows | none | run.Following |
| One tweet | POST /tweet-info | TwitterTweetScraper | none |
| List tweets | GET /list-tweets | TwitterListPostsScraper | none |
| Trends | GET /trends | TwitterTrendsScraper | none |
Search tweets
- Sorsa API
POST /search-tweets- snscrape
- TwitterSearchScraper
- Twint
- run.Search
Hashtag
- Sorsa API
POST /search-tweets- snscrape
- TwitterHashtagScraper
- Twint
- c.Search with #tag
A user's tweets
- Sorsa API
POST /user-tweets- snscrape
- TwitterUserScraper
- Twint
- c.Username
One profile
- Sorsa API
GET /info- snscrape
- TwitterUserScraper.entity
- Twint
- run.Lookup
Followers
- Sorsa API
GET /followers- snscrape
- none
- Twint
- run.Followers
Following
- Sorsa API
GET /follows- snscrape
- none
- Twint
- run.Following
One tweet
- Sorsa API
POST /tweet-info- snscrape
- TwitterTweetScraper
- Twint
- none
List tweets
- Sorsa API
GET /list-tweets- snscrape
- TwitterListPostsScraper
- Twint
- none
Trends
- Sorsa API
GET /trends- snscrape
- TwitterTrendsScraper
- Twint
- none
Two more requests have no library twin worth a row. GET /info-batch (opens in a new tab) returns up to 100 profiles in one request, where every library looks accounts up one by one, and GET /verified-followers (opens in a new tab) replaces twscrape's verified_followers and twikit's get_user_verified_followers.
Two jobs have no read-only replacement. A list of who liked a post (twikit's get_favoriters, Twint's --favorites) and a user's own likes or bookmarks are not public data that Sorsa API returns. Posting, following and DMs (twikit's create_tweet, follow_user, send_dm) stay with the official X API, since Sorsa API is read-only by design and never touches your X account.
#Why snscrape returns blocked (404)
snscrape returns blocked (404) for every Twitter scrape because it reads X logged out, and X stopped serving search and timelines to logged-out visitors on June 30, 2023. The maintainer opened issue #996 (opens in a new tab), "All Twitter scrapes are failing", the same day; it is still open, with 161 comments.
The library fetched a guest token, the pass X once gave anonymous visitors, and called the endpoints the logged-out web page used. Logging in is out of scope by design: issue #270 (opens in a new tab) says snscrape "does not and will not support logging into social network accounts". The last PyPI release, 0.7.0.20230622, shipped eight days before the break, so reinstalling, a new Python version or the development branch change nothing. The modules for other networks are a separate story; the Twitter module has no way back.
The search loop most tutorials taught moves over line for line. Your query string keeps its operators: from:, since:, until:, lang: and min_faves: work the same in the query field.
import itertools
import snscrape.modules.twitter as sntwitter
query = "from:lena_ships_python since:2026-10-01"
scraper = sntwitter.TwitterSearchScraper(query)
for tweet in itertools.islice(scraper.get_items(), 100):
print(tweet.date, tweet.likeCount, tweet.rawContent)
TwitterUserScraper("lena_ships_python") becomes user_tweets("lena_ships_python"), and TwitterHashtagScraper("yourtag") becomes search("#yourtag"). Our Twitter search operators reference lists every operator the query field accepts, back to posts from 2006.
#Twint: guest token errors and the archive
Twint is dead for good: its GitHub repository was archived by its owner on March 30, 2023, its last PyPI release (2.1.20) dates from April 29, 2020, and it reads X through the same logged-out guest token that snscrape lost.
Its failures started years before the archive. RefreshTokenException: Could not find the Guest token in HTML appears in issues from October 2020, and issue #1433 (opens in a new tab), opened on March 3, 2023, is the last report of it before the archive. The other error people quote, CRITICAL:root:twint.run:Twint:Feed:noData, means the page Twint parsed came back without the data it expected. Forks that patch token.py hit the same login wall in June 2023.
Twint's Config object maps to plain arguments. c.Search and c.Username become the query or the username, c.Since and c.Until move into the query as since: and until:, and c.Store_csv becomes a CSV writer you control.
import twint
c = twint.Config()
c.Search = "python"
c.Since = "2026-10-01"
c.Limit = 100
c.Store_csv = True
c.Output = "tweets.csv"
twint.run.Search(c)
twint.run.Followers(c) and twint.run.Following(c) become GET /followers and GET /follows, at up to 200 accounts per page. A whole timeline past Twint's old 3,200-tweet scroll limit is a search by date range, which our guide to download all tweets from a user walks through.
#twikit: the March 2026 break and twifork
twikit's latest release, 2.3.3 of February 7, 2025, fails on every call since X changed its web app on March 18, 2026. Issue #408 (opens in a new tab) reports Couldn't get KEY_BYTE indices and is still open, and issue #425 adds a KeyError from April 23, 2026.
The cause sits in how twikit talks to X. It logs in as a normal X user and calls the internal GraphQL endpoints the x.com web app uses, and each call needs an x-client-transaction-id header computed from a script that X serves. When X changed that script, twikit's parser stopped matching it. The upstream repository has 160 open issues and pull requests, and no release has followed.
A fork carries the code on. twifork (opens in a new tab) 2.4.0, released on August 30, 2026, keeps the from twikit import Client import and fixes the 2026 breaks, and its README is plain about the limits: password login "cannot be made to work", and guest access "is closed on X's side; use cookies". Running it means exporting auth_token and ct0 cookies from a browser session of an X account and watching that account for locks.
A twikit search such as search_tweet("python", "Latest") becomes one call to the helper:
from sorsa_helper import search
for t in search("python", limit=20):
print(t["created_at"], t["user"]["username"], t["full_text"])
twikit's 'Top' product maps to "order": "popular", and 'Latest' to "latest". The cookie file, the asyncio loop and the account behind them all drop out.
#twscrape: it works, on X accounts you supply
twscrape still works in 2026: version 0.20.1 shipped on August 25, 2026, and its repository was updated again on October 31. Its README (opens in a new tab) states the condition up front: it "requires authorized X/Twitter accounts", added from browser cookies that hold auth_token and ct0.
The library runs a pool of those accounts, so every account in it is at risk of a lock.
Three failures show up in practice:
- Locked or logged-out accounts. A pool with no active account waits, or raises
NoAccountError. - Cloudflare blocks. Open issue #337 (opens in a new tab) (September 12, 2026) logs
Blocked by Cloudflare: 403onuser_by_id. - Changes to X's web app. X adds flags to its internal GraphQL calls, and when one becomes required, twscrape raises
GqlFeaturesOutdatedErroruntil a release catches up.
twscrape's user_by_login, user_tweets and followers calls become two calls to the helper:
from sorsa_helper import followers, user_tweets
tweets = list(user_tweets("lena_ships_python", limit=100))
fans = list(followers("lena_ships_python", limit=1000))
No user ID lookup is needed, because POST /user-tweets and GET /followers take a username directly. A thousand followers come in five requests, at 200 per page.
#twscrape vs twikit vs snscrape: how they compare
twscrape is the only one of the three that still works from its official release, twikit works only through its fork, and snscrape cannot be fixed for X; none of them runs without X accounts today. The criteria that decide a replacement are whether it works now, what it needs from you, whether your code keeps working, how much one request returns and what 1,000 results cost.
| Criterion | Sorsa API | twscrape | twikit | snscrape |
|---|---|---|---|---|
| Works on X today | Yes | Yes | Through twifork | No |
| X account needed | None | A pool of them | One, by cookies | None, but dead |
| When X changes | Fixed on our side | Wait for a release | Fork patches it | Never fixed |
| Tweets per request | About 20; 100 by ID | About 20 | About 20 | Was about 20 |
| Account at risk | Never | Every one in the pool | The cookie account | None |
| Setup | One API key | Accounts, cookies, proxies | Cookie export | Nothing, returns nothing |
| Price per 1,000 tweets | From $0.07 | Accounts, proxies, time | Accounts, time | Free, no data |
Works on X today
- Sorsa API
- Yes
- twscrape
- Yes
- twikit
- Through twifork
- snscrape
- No
X account needed
- Sorsa API
- None
- twscrape
- A pool of them
- twikit
- One, by cookies
- snscrape
- None, but dead
When X changes
- Sorsa API
- Fixed on our side
- twscrape
- Wait for a release
- twikit
- Fork patches it
- snscrape
- Never fixed
Tweets per request
- Sorsa API
- About 20; 100 by ID
- twscrape
- About 20
- twikit
- About 20
- snscrape
- Was about 20
Account at risk
- Sorsa API
- Never
- twscrape
- Every one in the pool
- twikit
- The cookie account
- snscrape
- None
Setup
- Sorsa API
- One API key
- twscrape
- Accounts, cookies, proxies
- twikit
- Cookie export
- snscrape
- Nothing, returns nothing
Price per 1,000 tweets
- Sorsa API
- From $0.07
- twscrape
- Accounts, proxies, time
- twikit
- Accounts, time
- snscrape
- Free, no data
For a pipeline that has to run next month, choose Sorsa API: the same search operators and the same jobs as these libraries, about 20 tweets per search request or 100 per batch lookup by ID, 20 requests per second on every plan, and no X account that can be locked. It has been in production since 2022 with 6B+ requests served, first as TweetScout API.
#Move the fields your code reads
Sorsa API names its fields in snake case and nests the full author profile in user, so a migration renames a dozen attributes and keeps everything else. The table gives the old name in each library and the field that replaces it.
| Sorsa API field | snscrape, twscrape | twikit | Twint |
|---|---|---|---|
id (string) | id | id | id |
created_at (ISO 8601) | date | created_at | datetime |
full_text | rawContent | text | tweet |
user.username | user.username | user.screen_name | username |
user.display_name | user.displayname | user.name | name |
likes_count | likeCount | favorite_count | likes_count |
retweet_count | retweetCount | retweet_count | retweets_count |
reply_count | replyCount | reply_count | replies_count |
quote_count | quoteCount | quote_count | none |
view_count | viewCount | view_count | none |
conversation_id_str | conversationId | none | conversation_id |
quoted_status | quotedTweet | quote | none |
id(string)- snscrape, twscrape
id- twikit
id- Twint
id
created_at(ISO 8601)- snscrape, twscrape
date- twikit
created_at- Twint
datetime
full_text- snscrape, twscrape
rawContent- twikit
text- Twint
tweet
user.username- snscrape, twscrape
user.username- twikit
user.screen_name- Twint
username
user.display_name- snscrape, twscrape
user.displayname- twikit
user.name- Twint
name
likes_count- snscrape, twscrape
likeCount- twikit
favorite_count- Twint
likes_count
retweet_count- snscrape, twscrape
retweetCount- twikit
retweet_count- Twint
retweets_count
reply_count- snscrape, twscrape
replyCount- twikit
reply_count- Twint
replies_count
quote_count- snscrape, twscrape
quoteCount- twikit
quote_count- Twint
- none
view_count- snscrape, twscrape
viewCount- twikit
view_count- Twint
- none
conversation_id_str- snscrape, twscrape
conversationId- twikit
- none
- Twint
conversation_id
quoted_status- snscrape, twscrape
quotedTweet- twikit
quote- Twint
- none
For a large codebase, a small adapter keeps the old attribute names alive while you move the rest. It wraps each Sorsa API tweet in an object that answers to snscrape's and twscrape's names:
from datetime import datetime
from types import SimpleNamespace
def as_snscrape(t):
"""A Sorsa API tweet under snscrape/twscrape attribute names."""
u = t["user"]
return SimpleNamespace(
id=int(t["id"]),
url=f"https://x.com/{u['username']}/status/{t['id']}",
date=datetime.fromisoformat(t["created_at"].replace("Z", "+00:00")),
rawContent=t["full_text"],
lang=t.get("lang"),
likeCount=t["likes_count"],
retweetCount=t["retweet_count"],
replyCount=t["reply_count"],
quoteCount=t["quote_count"],
viewCount=t.get("view_count"),
user=SimpleNamespace(
username=u["username"],
displayname=u["display_name"],
followersCount=u["followers_count"],
),
)
for tweet in map(as_snscrape, search(query)): then feeds the old loop body unchanged. IDs come as strings in Sorsa API, so the adapter turns them back into integers the way snscrape gave them.
#What the same job costs
On Sorsa API, tweets from a search cost from $0.07 per 1,000, against $5.00 per 1,000 posts on the official X API, which also needs a developer account, OAuth and prepaid credits. The libraries charge no fee; they cost X accounts, proxies, and the hours spent each time X changes its web app.
Official X API
$5,000
for 1M tweets from search
$0.005 per post
Sorsa API
from$70
for 1M tweets from search
from $0.07 per 1,000
The official X API's pay-per-use pricing (opens in a new tab) stops at 3M post reads a month; past that only an Enterprise contract applies. Looking tweets up by ID in batches of 100 drops the Sorsa API price to $0.014 per 1,000, and follower lists cost from $0.007 per 1,000 at 200 per page. Failed requests are never charged.
#Run your old snscrape query on Sorsa API today
snscrape and Twint are gone, and the libraries that still work need X accounts that X has not locked. To keep a Twint, snscrape, twikit or twscrape job running without that risk, move it to Sorsa API: one key, your existing search queries, about 20 tweets per request from $0.07 per 1,000. Paste the helper above, swap one call, and your 100 free requests return about 2,000 tweets to check the output against what the old script produced.
#FAQ
Is twikit still maintained in 2026?
No, not upstream: twikit's latest release is 2.3.3 from February 7, 2025, and since X's change of March 18, 2026 every call fails with "Couldn't get KEY_BYTE indices" (issue #408, still open). The community fork twifork 2.4.0, released August 30, 2026, fixes that break, keeps the twikit import, and works only with cookies exported from a logged-in X account.
Does twscrape still work without an X account?
No. twscrape works in 2026, with version 0.20.1 from August 25, 2026, but its README says it requires authorized X accounts, added from cookies that hold auth_token and ct0. It runs on a pool of those accounts, and X can lock any of them.
Is there a fork of snscrape that works for Twitter?
No fork can bring it back for X. snscrape reads X logged out, and since June 30, 2023 X returns search and timelines only to logged-in users, so any fork that patches the guest token still ends in "blocked (404)". The maintainer ruled out logins in issue #270, so a fix would have to rewrite the library around logged-in accounts.
Can I keep my snscrape or Twint search queries?
Yes. Sorsa API's search takes X's own query syntax, so strings with from:, since:, until:, lang:, min_faves: and filter: work unchanged in the query field of POST /search-tweets. Set "order" to "latest" for the newest-first order snscrape returned, or "popular" for the Top tab, and the results come back about 20 per page with a cursor.
What is the best snscrape alternative for Twitter data?
For collecting public tweets the way snscrape did, without an X account, the best alternative is Sorsa API: the same search operators, about 20 tweets per search request from $0.07 per 1,000, 100 tweets per batch lookup by ID from $0.014 per 1,000, and 20 requests per second on every plan. It returns public data only and never asks for your X login or cookies, and 100 free requests come with every new account.
#How we checked
On November 2, 2026, we read the PyPI release history and the GitHub repository state of snscrape, Twint, twikit, twifork, twscrape, Scweet, ntscraper, tweety and Nitter, and the issues cited above. We took each library's method and attribute names from its source code on GitHub the same day. Every Sorsa API endpoint, parameter and field here matches the live API reference; the requests were written from it, and we did not run the library code against x.com.
Sources
- snscrape issue #996: All Twitter scrapes are failing (opens in a new tab)
- snscrape issue #270: Support for authentication (opens in a new tab)
- snscrape on PyPI (opens in a new tab)
- Twint repository (archived) (opens in a new tab)
- Twint issue #1433: Could not find the Guest token in HTML (opens in a new tab)
- twikit issue #408: ClientTransaction broken as of March 18, 2026 (opens in a new tab)
- twikit on PyPI (opens in a new tab)
- twifork README (opens in a new tab)
- twscrape README (opens in a new tab)
- twscrape issue #337: user_by_id blocked by Cloudflare (opens in a new tab)
- Scweet on PyPI (opens in a new tab)
- ntscraper README (opens in a new tab)
- Nitter repository (archived) (opens in a new tab)
- X API pay-per-use pricing (docs.x.com) (opens in a new tab)
- Sorsa API reference, OpenAPI
- Search operators (Sorsa API docs) (opens in a new tab)