Scrape Twitter / X without the official API.
Tweets, profiles, followers, trends and more.
Runs on Apify. You do not need X accounts, cookies or proxies.
- Configure and run from your browser, no code needed, or drive it from code with the Python API
- Search tweets, profile timelines, follower / following lists
- Export in different formats (JSON, CSV or XLSX)
- Free tier included; pay-as-you-go pricing is on the Actor page
Bring your own X accounts and proxies. Run it from Python or the CLI, inside your own infrastructure.
from Scweet import Scweet
s = Scweet(auth_token="YOUR_AUTH_TOKEN")
tweets = s.search("bitcoin", limit=100)Both give you the same data. Self-hosted: you run the code, and you manage the accounts and the proxies. Hosted: you press a button and get the results.
- Tweets — by keyword, hashtag, user, date range, engagement filters, language, location
- Profile timelines — a user's full tweet history, with replies and media tabs
- Tweets by id — full data for known tweet ids, their replies, and who reposted them
- Followers / Following — full account lists at scale, verified followers included
- User profiles — bio, follower count, verification status, by handle or by id
- People search & trends — find accounts by keyword, read what is trending now
Three steps from nothing to tweets. One account, one call, one result.
1. Install
pip install -U Scweet2. Get your auth_token
Log into x.com → DevTools F12 → Application → Cookies → https://x.com → copy the auth_token value. That one value is all you need; Scweet builds the rest.
Use a dedicated account, never your personal one.
3. Scrape
from Scweet import Scweet
s = Scweet(auth_token="YOUR_AUTH_TOKEN")
tweets = s.search("bitcoin", limit=100)
for tweet in tweets:
print(tweet["text"])That is the whole first run. On the next run, reuse the same accounts with no credentials:
s = Scweet() # reads the state file scweet_state.db
tweets = s.search("ethereum", limit=100, save=True) # save=True writes a CSVAlways set
limit. Without it, a run continues until the daily cap of the account.
Next: add a proxy for real volume, use several accounts, or read the full documentation.
A proxy is optional for a small run and recommended for real volume, because many requests from one IP raise the risk to an account. Pass one URL for all accounts:
s = Scweet(auth_token="YOUR_AUTH_TOKEN", proxy="http://user:pass@proxy.example.com:8000")On a rotating provider, put {session} in the URL to give each account its own exit IP: http://user,session-{session}:pass@proxy.example.com:8000. For a proxy per account, see Multiple accounts & proxies.
All methods have async variants:
asearch(),aget_profile_tweets(),aget_followers(), etc.
tweets = s.search(
"AI agents",
since="2026-01-01",
from_users=["elonmusk"],
min_likes=50,
limit=200,
save=True,
)tweets = s.get_profile_tweets(["elonmusk"], limit=200)followers = s.get_followers(["elonmusk"], limit=1000)
following = s.get_following(["elonmusk"], limit=1000)
verified = s.get_verified_followers(["elonmusk"], limit=1000)profiles = s.get_user_info(["githubstatus", "elonmusk"])
profiles = s.get_user_info(user_ids=["44196397"]) # numeric ids work tootweets = s.get_tweet_info(["1866123456789", "1866123456790"]) # up to 50 per request
replies = s.get_tweet_replies("1866123456789", limit=100)
reposters = s.get_reposters("1866123456789", limit=100)people = s.search_users("python developer", limit=50)
trends = s.get_trending()
media = s.get_profile_media(["nasa"], limit=100)
tweets = s.get_profile_tweets(["nasa"], limit=100, include_replies=True)For the full list of supported search operators, see twitter-advanced-search.
# Search with proxy, save to CSV
scweet --auth-token YOUR_AUTH_TOKEN --proxy http://user:pass@host:port \
search "bitcoin" --since 2026-01-01 --limit 500 --save
# Followers, saved as JSON
scweet --auth-token YOUR_AUTH_TOKEN \
followers elonmusk --limit 1000 --save --save-format jsonFor multi-account runs, use --cookies-file cookies.json.
For higher throughput and reduced ban risk, use multiple dedicated accounts with per-account proxies.
Running Scweet locally at any real volume usually means dedicated accounts and proxies. You can use a single proxy, a rotating proxy, or assign one per account. On a rotating provider, put {session} in the proxy URL to give each account its own session — see "Proxy modes" in DOCUMENTATION.md.
cookies.json format:
[
{ "username": "acct1", "cookies": { "auth_token": "..." }, "proxy": "http://user1:pass1@host1:port1" },
{ "username": "acct2", "cookies": { "auth_token": "..." }, "proxy": "http://user2:pass2@host2:port2" }
]s = Scweet(cookies_file="cookies.json") # proxies are read from the file, one per accountNever use your personal Twitter/X account for scraping. Use dedicated accounts only.
One page of X is easy to fetch. 10,000 tweets is not, because accounts get rate-limited, cookies expire, and X changes its API.
Your run finishes
- A wide date range is split into intervals that run in parallel. If X stops one interval early, the others still fill.
- If X ends a page chain early, Scweet continues from the oldest tweet it received.
- If a run stops,
resume=Truecontinues from the last saved point instead of starting again.
Your accounts stay usable
- Scweet reads the rate-limit headers of X and stops each account 2 requests before its limit, so X does not block it.
- Scweet identifies the cause of each error. A bad request, an old query id and a dead session are handled differently, so a small error does not cost you an account.
- Scweet records the state of each account (locked, suspended, rate-limited) and waits the needed time before it uses that account again.
It keeps working when X changes
- X changes the ids of its internal API without notice. Scweet reads the new ids from the JavaScript files of X, at startup or when you call
refresh_manifest().
It is easy to work with
- 12 read operations, one consistent row shape, sync and async, a real CLI, and CSV/JSON output built in.
- 25 fields per tweet, including view counts, quotes, bookmarks, language and the nested quoted or retweeted post.
Or let us run it for you
- The hosted version does all of the above on our accounts and proxies. Free tier included.
Also on twint and snscrape: both are unmaintained and no longer work against X's current backend. If you are migrating from either, Scweet covers the same ground and more.
- Only publicly visible content is accessible — private/protected accounts are not supported
- Relies on undocumented X web endpoints; breakage is always possible after platform changes. Scweet self-heals by scraping fresh query IDs and feature flags from X's own bundles — at startup with
manifest_scrape_on_init=True, or on demand at any time:s = Scweet(auth_token="...", manifest_scrape_on_init=True) changes = s.refresh_manifest() # or: scweet refresh-manifest
- Cookies can expire and may need periodic refreshing
- A single account typically handles hundreds to a few thousand tweets per day before hitting rate limits; multi-account pooling scales proportionally
- Proxies and dedicated accounts are strongly recommended for anything beyond light testing
- Username/password login is not supported. X's anti-automation defenses make programmatic login unreliable and likely to trigger account locks. Scweet authenticates with browser cookies (
auth_token) extracted from an active session instead
Full API reference, config options, structured search filters, async patterns, resume, proxies, and troubleshooting:
- Account setup
- Search API
- Profile tweets
- Tweet lookup & replies
- Followers / Following
- User info
- Search users & trends
- Manifest refresh
- Saving results
- Resume interrupted searches
- Controlling limits
- Configuration reference
- Account management (ScweetDB)
- Async usage
- Error handling
- CLI reference
For advanced Twitter search operators, see twitter-advanced-search.
FAQ
Does it work without an official Twitter API key? Yes. Scweet calls X's internal GraphQL API — the same one the web app uses. No developer account or API key required.
Is it a replacement for twint or snscrape? Yes. Both are broken as of 2024–2025. Scweet uses a different, currently-working approach: cookies + GraphQL instead of legacy unauthenticated endpoints.
How many tweets can I scrape? A single account typically handles hundreds to a few thousand tweets per day before hitting rate limits. Multi-account pooling scales this proportionally. The hosted Apify actor manages accounts and rate limits automatically.
Will my account get banned? Never use your personal account — use dedicated accounts only. To reduce risk further: use multiple accounts (distributes load) and pair each with a proxy (prevents all requests from one IP).
Does it work for private accounts? No. Only publicly visible content is accessible.
Does it still work in 2025 / 2026? Yes — last verified with the 5.8.0 release (2026-09-15) against X's current GraphQL API.
Have a question or want to share what you built with Scweet? Open a thread in GitHub Discussions.
Found it useful? Star the repo
Bug reports, feature suggestions, and PRs are welcome. See CONTRIBUTING.md.
MIT License
