Twitter/X tools for LangChain agents – TwittrAPI
langchain-twittrapi is a set of LangChain tools for TwittrAPI, a REST API for public Twitter/X data. LangChain and LangGraph agents can read tweets, profiles, followers, search results, lists, communities and trends. Pay as you go from $0.065 per 1,000 calls, no X developer account. Not affiliated with X Corp.
Get an API key: twittrapi.com/start · Pricing · Docs · Status · also available on RapidAPI
SDKs and integrations: Python · Node.js · Go · MCP server · n8n · Make · Apify · LlamaIndex · Agent skill · Examples
All tools are read-only. They are built on the official twittrapi Python SDK.
Install
pip install -U langchain-twittrapi
Python 3.10 or newer. Works with langchain-core 1.x.
Authentication
Use either a direct TwittrAPI key or a RapidAPI key.
export TWITTRAPI_API_KEY="your-twittrapi-key" # direct API
# or
export RAPIDAPI_KEY="your-rapidapi-key" # RapidAPI
Or pass the key in code:
from langchain_twittrapi import TwittrAPIToolkit
toolkit = TwittrAPIToolkit(api_key="your-twittrapi-key") # direct API
toolkit = TwittrAPIToolkit(rapidapi_key="your-rapidapi-key") # RapidAPI
If both environment variables are set, TWITTRAPI_API_KEY wins.
Quickstart
Use one tool
from langchain_twittrapi import GetUserByUsernameTool
tool = GetUserByUsernameTool()
print(tool.invoke({"username": "jack"}))
Give an agent all the tools
pip install -U langchain "langchain[anthropic]"
from langchain.agents import create_agent
from langchain_twittrapi import TwittrAPIToolkit
tools = TwittrAPIToolkit().get_tools()
agent = create_agent(
"anthropic:claude-opus-5-5",
tools=tools,
system_prompt="You research X (Twitter) with the tools you have. Cite tweet IDs.",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What has @jack posted this week? Summarize it."}]}
)
print(result["messages"][-1].content)
Any chat model that supports tool calling works. To pick a subset of tools:
tools = TwittrAPIToolkit().get_tools(["search_tweets", "get_tweet"])
Async
Every tool supports ainvoke. The toolkit creates one AsyncTwittrAPI client for async calls, so async agents do not block on HTTP.
result = await agent.ainvoke({"messages": [{"role": "user", "content": "Trending in the US?"}]})
Tools
| Tool | Class | What it does |
|---|---|---|
get_user_by_username |
GetUserByUsernameTool |
Profile by handle, including the numeric user ID |
get_user_by_id |
GetUserByIdTool |
Profile by numeric user ID |
get_user_tweets |
GetUserTweetsTool |
A user's recent tweets (by user_id or username) |
get_followers |
GetFollowersTool |
Accounts that follow a user |
get_following |
GetFollowingTool |
Accounts a user follows |
search_tweets |
SearchTweetsTool |
Search with X operators (from:, lang:, since:, min_faves: ...) |
get_tweet |
GetTweetTool |
A tweet with its reply thread |
get_tweet_retweets |
GetTweetRetweetsTool |
Users who retweeted a tweet |
get_tweet_quotes |
GetTweetQuotesTool |
Tweets that quote a tweet |
get_list_tweets |
GetListTweetsTool |
Tweets from an X list |
get_community_tweets |
GetCommunityTweetsTool |
Tweets posted in an X Community |
get_trends |
GetTrendsTool |
Trending topics by WOEID (1 = worldwide) |
get_trend_locations |
GetTrendLocationsTool |
Locations that have trends, with their WOEIDs |
What the tools return
The tools return the API's simple format as compact JSON text: flat, camelCase tweets and users with a fixed schema (id, text, author, counts, media, ...). It uses far fewer tokens than X's raw JSON. Lists come as {"data": [...], "nextCursor": ..., "previousCursor": ..., "hasNextPage": ...}, single objects as {"data": {...}}.
For X's raw JSON (every field X sends: cards, polls, edit history, ...), opt out per toolkit or per tool:
TwittrAPIToolkit(api_response_format="raw")
GetTweetTool(api_response_format="raw")
(The option is named api_response_format because LangChain tools already have a response_format field.)
Responses can be large, so each result is cut at max_chars characters (default 20,000). When that happens the text ends with a [TRUNCATED: ...] marker that says how much was cut.
Paginated tools print the next-page cursor on the first line, before the JSON, so it is never lost to truncation:
next_cursor: DAABCgABF...
Pass next_cursor as `cursor` to get the next page.
{"data":[...],"nextCursor":"DAABCgABF...","previousCursor":"...","hasNextPage":true}
On the last page (hasNextPage is false) the first line says so instead.
Change the limit per toolkit or per tool:
TwittrAPIToolkit(max_chars=8_000)
GetTweetTool(max_chars=50_000)
Errors
API errors (bad key, no balance, not found, rate limit) and invalid arguments are returned to the model as the tool result, starting with TwittrAPI error: or Invalid arguments:. When the tool runs from a tool call, the ToolMessage has status="error". To raise instead, pass handle_tool_error=False.
Requests that fail with 429, 5xx or a network error are retried by the SDK.
Bring your own client
To change timeouts or retries, build the SDK clients yourself and pass them in:
from twittrapi import AsyncTwittrAPI, TwittrAPI
from langchain_twittrapi import TwittrAPIToolkit
toolkit = TwittrAPIToolkit(
client=TwittrAPI(api_key="...", timeout=30, max_retries=4),
async_client=AsyncTwittrAPI(api_key="...", timeout=30, max_retries=4),
)
If you pass only client, async calls run it in a worker thread.
Development
python -m venv .venv && source .venv/bin/activate
pip install -e . pytest pytest-asyncio langchain-tests
pytest
Support
Questions, bugs or billing: support@twittrapi.com. Issues with this package: GitHub issues.
License
MIT. See LICENSE.
Not affiliated with X Corp.
Metadata
Release files for langchain-twittrapi 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| langchain_twittrapi-0.2.0.tar.gz | 32.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langchain_twittrapi-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.0 kB
Release files / langchain_twittrapi-0.2.0.tar.gz
| Download URL | langchain_twittrapi-0.2.0.tar.gz |
|---|---|
| Size | 32.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c73226dc37d576d03922b2f88a963724ef651e1049f3f6d96fd321e13b36289a
|
|
BLAKE2b-256 checksum How to use checksums |
f8ba5bdceb5848654061e28cc8d07316e27f75b7bbf1ca17d9d7f1e772cd8c4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / langchain_twittrapi-0.2.0-py3-none-any.whl
| Download URL | langchain_twittrapi-0.2.0-py3-none-any.whl |
|---|---|
| Size | 13.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4e9f0cfa16e8b463f3457ccbd6468590e06e0090c41fa8968ed0e1727c1923de
|
|
BLAKE2b-256 checksum How to use checksums |
1a91258d26801206c13824ab6347e1e5d2a63a8ffd0ae278972f634ed321b0b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log