CLI tool
Altimis/Scweet avatar
Altimis/Scweet

Scweet: scraping X without the official API, and the account risk that comes with it

Scrape tweets, profiles, followers and following from Twitter/X, no API key needed. Python library with smart multi-account pooling, proxy support and async.

1,654 stars286 forksPythonMIT

At a glance

What is it?
Scweet is a Python library and CLI that pulls tweets, profiles, follower lists and trends from X by reusing a session cookie instead of an API key, with multi-account pooling, proxies and async variants. The trade-off is that the calling account carries the risk.
Who is it for?
Scweet fits a researcher or analyst who needs X data quickly and can absorb account-level risk, and it fits a team that would rather run the Apify hosted version than manage sessions and proxies. It is a poor fit for a production system that needs a stable, contractual data source, for anyone unwilling to run code under an X account that can be locked, and for compliance contexts where scraping collected data would not be permitted.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

No API key, just a session cookie from x.com

Scweet exists because the official X API is slow to get into and priced accordingly. The library bypasses it entirely: it signs requests with a session cookie that a user copies from their own browser session, so a caller gets tweet, profile, follower and trend data without registering for an API key or a developer tier.

The mechanism is visible in the dependency list. requirements.txt pulls in curl_cffi, which impersonates browser TLS fingerprints, XClientTransaction, which generates the transaction tokens X now requires on GraphQL endpoints, pydantic for the response models, SQLAlchemy 2.0 with sqlmodel on top, python-dotenv for environment variables, and beautifulsoup4 for pages where the HTML is still the only option. The GraphQL endpoint is the target for structured data, and the XClientTransaction dependency exists to keep those requests looking like they came from the web client.

The result is a library that sits in an unusual category. It is a scraping tool built like an API client, with typed methods, a session object, an async variant for every call, and a state database that remembers your accounts between runs. That combination is what makes it pleasant to use, and it is also exactly what makes the legal and operational exposure the same as any other automated access to a logged-in site.

One Scweet object, a state file, and every method with an async twin

The public surface is small. You construct a Scweet instance, optionally with an auth_token and a proxy, then call methods on it. The class holds the session state and the account pool, and the same object exposes search, profile timeline, tweet lookup by id, followers, following, user profiles, people search and trends.

Persistence is handled locally. The documented state file is scweet_state.db, and a second instantiation with no credentials reads that file, so the first call pays the cost of establishing sessions and later runs reuse them. SQLModel and SQLAlchemy sit underneath that persistence layer, and python-dotenv is there so tokens can be kept in a .env file rather than in source.

Every method has an async counterpart, with names prefixed by a: asearch(), aget_profile_tweets(), aget_followers() and so on. The repository ships examples/async_example.py and examples/sync_example.py, which is a reasonable signal for how the two styles are meant to be used side by side. Practically, the async variants are what make a multi-account pool worth having, since a blocking call holds a worker for the whole request cycle.

Installing the library and running the first search

The install is a single pip command from PyPI.

bash
pip install -U Scweet

The only other input is an auth_token. The documented procedure is to log into x.com, open the browser developer tools, go to the Application tab, select the Cookies for https://x.com, and copy the auth_token value. The README is emphatic that a dedicated account should be used rather than a personal one, which is sound advice given what follows.

With a token in hand, the first real call looks like this:

python
from Scweet import Scweet

s = Scweet(auth_token="YOUR_AUTH_TOKEN")
tweets = s.search("bitcoin", limit=100)

for tweet in tweets:
    print(tweet["text"])

The result is a list of tweet dicts, and the text field is a plain key, so the output drops straight into a pandas dataframe or a JSON export without a schema layer in between.

One instruction in the documentation deserves repeating because ignoring it looks like a hang rather than a bug: always set limit. Without it, a run continues until the daily cap of the account is reached. That is the cap of the account you supplied the cookie for, so an unlimited run spends the quota of a real session that you also use for reading tweets.

Saving results and reusing sessions across runs

Once the first run works, the credentials do not need to be passed again. A plain instantiation reads the state file, and the save flag writes the results out as a CSV.

python
s = Scweet()                       # reads the state file scweet_state.db
tweets = s.search("ethereum", limit=100, save=True)   # save=True writes a CSV

The save option is a convenience for the analyst workflow rather than a pipeline feature. For anything scheduled, you would be reading the CSV back in or calling the API and formatting the output yourself, and the hosted Apify option is the one that advertises exports in JSON, CSV or XLSX directly.

Filtering happens on the search call, which is where the method earns its keep. The documented parameters cover a date range, a list of source accounts, and an engagement floor, and the README example combines them:

python
tweets = s.search(
    "AI agents",
    since="2026-01-01",
    from_users=["elonmusk"],
    min_likes=50,
    limit=200,
    save=True,
)

Doing this filtering server side matters on a scraper, because the cost of a request is roughly constant while the cost of transferring and filtering a large unfiltered result is not. The language and location filters documented in the README follow the same pattern.

Multiple accounts and per account proxies for volume work

Volume is where the library stops being a convenience and starts being a liability, so the design decisions here are worth reading carefully. A single proxy URL can be attached to the session, and many requests from one IP raise the risk to an account, which the documentation says plainly.

python
s = Scweet(auth_token="YOUR_AUTH_TOKEN", proxy="http://user:[email protected]:8000")

On a rotating provider, putting {session} in the proxy URL gives each account its own exit IP, in the form http://user,session-{session}:[email protected]:8000.

For one proxy per account, the README points to the multiple accounts and proxies section of the documentation.

The honest assessment: the multi-account pool is an anti-detection and throughput mechanism. It spreads requests across accounts and IPs so that a single account hitting a rate limit does not stop the run. That is a legitimate design for a data tool, but it is also a design whose failure mode is account suspension, and the cost of a bad configuration is spread across accounts you may have paid for.

The hosted Apify actor and how it differs from the library

Scweet ships a second way to run, hosted on Apify, and the difference in approach is substantial enough to matter for the adoption decision. The hosted version is described as needing no X accounts, cookies or proxies, configured and run from a browser with no code, or driven from code through the Apify Python API. Exports are available as JSON, CSV or XLSX, a free tier is included, and pay-as-you-go pricing sits on the Actor page.

So the split is ownership of the risk. Self-hosted, you run the code and you manage the accounts and the proxies, which means your accounts can be locked and your data flow is yours to secure. Hosted, the operator manages the session side and you are billed for it, which means you do not hold credentials but you do not control where the scraping happens either.

For a company with an existing Apify subscription, the hosted path is the lower effort and the smaller operational surface. For a researcher who already has a spare account and wants raw objects in Python rather than a file, the self-hosted library is the better fit. Note that the hosted option includes a free tier, with pay-as-you-go pricing beyond it, and both paths return the same data.

What the repository does and does not tell you

The project is organized like a maintained library rather than a script dump. There is a pyproject.toml with a setuptools build backend, a setup.py that reads the version from Scweet/__version__.py and parses requirements.txt while keeping environment markers, a CHANGELOG.md, CONTRIBUTING.md, and a Makefile that gives contributors named targets: make test runs the pytest suite against tests/, make docs-install installs the documentation toolchain, and make docs builds the mkdocs site with a strict flag that stops the build on a broken link. There is a separate make docs-check target that runs scripts/check_docs_site.py to confirm the built site contains every section of every document, and AGENTS.md, CLAUDE.md and a docs directory alongside it.

The packaging metadata is explicit too. The project is named Scweet, the licence field reads MIT and the repository carries a LICENSE.txt, and the author is listed as Yassine AIT JEDDI. The documentation is published as a mkdocs site at altimis.github.io/Scweet with a full reference, and the README links to DOCUMENTATION.md for per-method detail, including a cookies.json example in the examples directory for supplying sessions in bulk.

The repository is not archived and the last push was on 2026-09-29, with v5.8.1 released the same day after v5.8.0 on 2026-09-15 and v5.7.0 on 2026-09-14. What the documentation does not cover is the legal side: there is no guidance in it about the terms of service of the platform, about what you may do with the collected data, or about how long a session survives before it is challenged. Those questions have to be answered by you, not by the library.

Editorial conclusion

Scweet fits a researcher or analyst who needs X data quickly and can absorb account-level risk, and it fits a team that would rather run the Apify hosted version than manage sessions and proxies. It is a poor fit for a production system that needs a stable, contractual data source, for anyone unwilling to run code under an X account that can be locked, and for compliance contexts where scraping collected data would not be permitted. Before adopting, read the auth_token guidance in the README, run the search call with an explicit limit on a dedicated account, and check the terms of the accounts and data you intend to collect.

Frequently asked questions

How do I get an auth_token for Scweet?

Log into x.com, open the browser developer tools with F12, go to the Application tab, select the Cookies for https://x.com, and copy the auth_token value. The README recommends using a dedicated account rather than a personal one.

Do I need an X API key to use Scweet?

No. Scweet works without an official API key. In the self-hosted mode you supply an auth_token cookie and manage your own accounts and proxies, and the hosted Apify version is described as needing no X accounts, cookies or proxies at all.

Why should I always pass a limit when searching with Scweet?

Without a limit, a run continues until the daily cap of the account is reached, since the cap belongs to the session whose cookie you supplied. Always set limit so a run ends on your terms rather than on the account's quota.

Does Scweet support async scraping?

Yes. Every method has an async variant, with names prefixed by a, such as asearch(), aget_profile_tweets() and aget_followers(). The repository includes an async example alongside a sync one.

What is the Scweet licence and is the project still updated?

The project is released under the MIT licence, with a LICENSE.txt in the repository and the licence field set in the packaging metadata. The repository is not archived and the last push was on 2026-09-29, with v5.8.1 released the same day.

Official sources

  1. Altimis/Scweet on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/altimis-scweet.svg)](https://hysenlabs.com/projects/altimis-scweet)

Was this useful?