Skip to main content

A maintained fork of twikit — Twitter/X API scraper for Python, no API key required.

Project description

twifork

A Twitter / X API scraper for Python — no API key required.
A maintained fork of d60/twikit, fixed for the 2026 breakages that make the upstream release unusable.

Python 3.8+ MIT License Stars

Drop-in replacement — the package still imports as twikit, so existing code (from twikit import Client) keeps working unchanged.


Install

pip install git+https://github.com/PawiX25/twifork.git

Optional browser-TLS impersonation (gets past some 403 walls):

pip install "twikit[impersonate] @ git+https://github.com/PawiX25/twifork.git"

Why this fork?

The upstream PyPI release (twikit==2.3.3) is broken in several ways as of 2026. twifork fixes them — each item links to the upstream issue it resolves:

  • ClientTransaction / Couldn't get KEY_BYTE indices — updated ondemand.s.js parsing for the new X webpack bundle, so GraphQL requests work again. (#408, #409, #304)
  • Intermittent / sticky 404 on SearchTimeline and friends/list — the x-client-transaction-id animation key was missing X's frame_time rounding step, so on some Client sessions every strict request 404'd until the client was recreated. Restored, so the semi-random 404s are gone. (#357, #397)
  • KeyError on missing optional fields in User.__init__ and Client.request — defensive .get() parsing. (#417)
  • Empty user name / screen_name (e.g. in search results) — X moved name, screen_name, created_at, avatar, location, and more out of legacy into new sub-objects; these are now read with a legacy fallback.
  • get_tweet_by_id KeyError: 'itemContent' — handles both the legacy and the new trailing-cursor shapes. (#332, #363)
  • KeyError: 'entries' / IndexError on get_user_tweets for accounts with no visible tweets — empty / cursor-less timelines return an empty result instead of crashing. (#361, #216)
  • get_trends deprecated / returns nothing — rebuilt on top of GenericTimelineById; also adds get_explore_page(). (#389)
  • RecursionError on rate-limit — the 429 recovery path no longer recurses.
  • GuestClient.activate() 404 — the guest client now sends a User-Agent header and parses user fields defensively. (#402, #385)
  • get_latest_friends 404 — routed through the GraphQL Following endpoint after the v1.1 endpoint was retired. (#397)
  • 'Client' object has no attribute '_ui_metrix' — fixed the captcha unlock path. (#333)
  • get_bookmark_folders().next() infinite loop — fixed malformed pagination variables. (#334, #335)
  • get_latest_timeline / get_list_tweets dropping conversation entries — home- and list-conversation entries are now unpacked. (#336, #337, #340)
  • Media.source_url for the full-resolution image (#376), and Tweet.quoted_status_id for the quoted tweet id (#222).

Issues that stem from X-side restrictions (account suspension, Cloudflare/IP blocks, captcha, automation limits) aren't fixable in the library and are out of scope.

Browser TLS impersonation (optional)

Some X endpoints reject the default httpx TLS fingerprint with a 403 (HTML) response even when the request is valid. Installing the optional curl_cffi backend and passing impersonate= routes requests through a real browser TLS fingerprint, which avoids those 403s:

client = Client('en-US', impersonate='chrome124')

Quick start

Define a client and log in.

import asyncio
from twikit import Client

client = Client('en-US')

async def main():
    await client.login(
        auth_info_1='example_user',
        auth_info_2='email@example.com',
        password='password0000',
        cookies_file='cookies.json'
    )

asyncio.run(main())

Post a tweet with media attached.

media_ids = [
    await client.upload_media('media1.jpg'),
    await client.upload_media('media2.jpg'),
]
await client.create_tweet(text='Example Tweet', media_ids=media_ids)

Search the latest tweets for a keyword.

tweets = await client.search_tweet('python', 'Latest')
for tweet in tweets:
    print(tweet.user.name, tweet.text, tweet.created_at)

A few more common calls.

await client.get_user_tweets('123456', 'Tweets')   # a user's tweets
await client.send_dm('123456789', 'Hello')          # send a DM
await client.get_trends('trending')                 # trending topics

More examples (upstream, still apply): https://github.com/d60/twikit/tree/main/examples

Features

  • No API key — works by scraping the web client.
  • Free & open source (MIT).
  • Drop-in twikit replacement — same import, your code doesn't change.
  • Tweets, search, timelines, trends, users, DMs, media, bookmarks, and more.

Documentation

Full API reference (upstream — the package surface is the same): https://twikit.readthedocs.io/en/latest/twikit.html

Community

Discord

Contributing

Found a bug or have a fix? Open an issue or PR on twifork issues.

If twifork saved you a headache, consider leaving a ⭐.

Credits

twifork is a fork of d60/twikit by @d60 — all upstream credit goes to the original authors. Licensed under the MIT License.

Disclaimer

twifork is an independent, unofficial project. It is not affiliated with, endorsed by, or sponsored by X Corp. "X" and "Twitter" are trademarks of X Corp. Use it in accordance with applicable terms and laws.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

twifork-2.3.3.tar.gz (41.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

twifork-2.3.3-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

Details for the file twifork-2.3.3.tar.gz.

File metadata

  • Download URL: twifork-2.3.3.tar.gz
  • Upload date:
  • Size: 41.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for twifork-2.3.3.tar.gz
Algorithm Hash digest
SHA256 381fa148b524773e39aeb5cfb3e47d2a0a632c60f23de16c1d37f9d454fa553d
MD5 f5a93f9ca7f091db91347322f816decb
BLAKE2b-256 7538d562cefcd1225cc2b1f7d11c3a7bba4e48318407003a2852f9ae0d410d39

See more details on using hashes here.

File details

Details for the file twifork-2.3.3-py3-none-any.whl.

File metadata

  • Download URL: twifork-2.3.3-py3-none-any.whl
  • Upload date:
  • Size: 53.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for twifork-2.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d1cbb1d002d105a67273f6ca5c3ac5a78982792db64dbcd7cede19d8744f683a
MD5 bbd8f3e33ee53a8d9f7e54bf67288ddb
BLAKE2b-256 77827f1f8cac828bcf2bdadcb8e0dea0bd372801e152e6e8b574dd164115aa64

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page