Twitter/X tools for LlamaIndex agents – TwittrAPI
llama-index-tools-twittrapi is a set of LlamaIndex tools for TwittrAPI, a REST API for public Twitter/X data. LlamaIndex 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 · LangChain · Agent skill · Examples
All tools are read-only. They are built on the official twittrapi Python SDK.
Install
pip install -U llama-index-tools-twittrapi
Python 3.10 or newer. Works with llama-index-core 0.13 and 0.14.
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 llama_index.tools.twittrapi import TwittrAPIToolSpec
spec = TwittrAPIToolSpec(api_key="your-twittrapi-key") # direct API
spec = TwittrAPIToolSpec(rapidapi_key="your-rapidapi-key") # RapidAPI
If both environment variables are set, TWITTRAPI_API_KEY wins.
Quickstart
Call a tool directly
from llama_index.tools.twittrapi import TwittrAPIToolSpec
spec = TwittrAPIToolSpec()
print(spec.get_user_by_username("jack"))
Give an agent all the tools
pip install -U llama-index-llms-anthropic
import asyncio
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.anthropic import Anthropic
from llama_index.tools.twittrapi import TwittrAPIToolSpec
agent = FunctionAgent(
tools=TwittrAPIToolSpec().to_tool_list(),
llm=Anthropic(model="claude-opus-5-5"),
system_prompt="You research X (Twitter) with the tools you have. Cite tweet IDs.",
)
async def main() -> None:
response = await agent.run("What has @jack posted this week? Summarize it.")
print(response)
asyncio.run(main())
Any LLM that supports function calling works. To pick a subset of tools:
tools = TwittrAPIToolSpec().to_tool_list(
spec_functions=[("search_tweets", "asearch_tweets"), ("get_tweet", "aget_tweet")]
)
Async
Every tool has a sync method (get_tweet) and an async one (aget_tweet). Agents that run tools asynchronously, such as FunctionAgent, use the async methods, which call the SDK's AsyncTwittrAPI client and do not block the event loop.
Tools
| Tool | What it does |
|---|---|
get_user_by_username |
Profile by handle, including the numeric user ID |
get_user_by_id |
Profile by numeric user ID |
get_user_tweets |
A user's recent tweets (by user_id or username) |
get_followers |
Accounts that follow a user |
get_following |
Accounts a user follows |
search_tweets |
Search with X operators (from:, lang:, since:, min_faves: ...) |
get_tweet |
A tweet with its reply thread |
get_tweet_retweets |
Users who retweeted a tweet |
get_tweet_quotes |
Tweets that quote a tweet |
get_list_tweets |
Tweets from an X list |
get_community_tweets |
Tweets posted in an X Community |
get_trends |
Trending topics by WOEID (1 = worldwide) |
get_trend_locations |
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:
TwittrAPIToolSpec(api_response_format="raw")
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:
TwittrAPIToolSpec(max_chars=8_000)
Errors
API errors (bad key, no balance, not found, rate limit) and invalid arguments raise TwittrAPIToolError with a message that starts with TwittrAPI error: or Invalid arguments:. LlamaIndex agents catch it and pass the message to the model as a tool error (ToolOutput.is_error), so the model can correct itself.
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 llama_index.tools.twittrapi import TwittrAPIToolSpec
spec = TwittrAPIToolSpec(
client=TwittrAPI(api_key="...", timeout=30, max_retries=4),
async_client=AsyncTwittrAPI(api_key="...", timeout=30, max_retries=4),
)
If you pass only client, the async methods run it in a worker thread.
Development
python -m venv .venv && source .venv/bin/activate
pip install -e . pytest pytest-asyncio
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 llama-index-tools-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 | |
|---|---|---|---|
| llama_index_tools_twittrapi-0.2.0.tar.gz | 30.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| llama_index_tools_twittrapi-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.6 kB
Release files / llama_index_tools_twittrapi-0.2.0.tar.gz
| Download URL | llama_index_tools_twittrapi-0.2.0.tar.gz |
|---|---|
| Size | 30.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4d3eb2431a54ed52470f04914a21879c1c9a1d0a54e5b576e78073d65eaa80d
|
|
BLAKE2b-256 checksum How to use checksums |
4f15e600654fad72fa4a6583713f9ad3d4753531b42c617a263de9c41d028143
|
| 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 / llama_index_tools_twittrapi-0.2.0-py3-none-any.whl
| Download URL | llama_index_tools_twittrapi-0.2.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
54ea3343d739097f22c9ff09842719e9cd888e39769f64228ddd7dc54332cfe7
|
|
BLAKE2b-256 checksum How to use checksums |
73f505c6b5d28da274ebba0fdb8b224c64a9f5a0e7b481e683c9541265c051e2
|
| 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