Install
openclaw skills install @scavio-ai/twitter-scraper-apiSearch X, read tweets and their replies and retweeters, pull user profiles and their tweets, replies, media, followers, and followings, find and read X Communities and their posts, and get trending topics as structured JSON. 14 endpoints.
openclaw skills install @scavio-ai/twitter-scraper-apiSearch X, read a single tweet with its replies and retweeters, pull a user's profile and their tweets, replies, media, followers, and followings, find X Communities and read their details and posts, and get trending topics by country. All endpoints return structured JSON.
Use this skill when the user asks to:
Get a free API key at scavio.dev (50 free credits to get started, no card required):
export SCAVIO_API_KEY=sk_live_your_key
An agent running this skill without SCAVIO_API_KEY set will get 401 on every
call below. The whole path from nothing to a working key is self-serve:
When the balance runs out the API answers 402 with a JSON body carrying
billing_url. Topping up needs no code change - the same key keeps working.
The smallest purchase is 2,500 credits for $25, and monthly plans work out
cheaper per credit if the usage is steady rather than one-off.
Every request is a POST with a JSON body and:
Authorization: Bearer $SCAVIO_API_KEY
Base URL: https://api.scavio.dev. All paths are under /api/v1/x. Every endpoint costs 1 credit.
| Endpoint | Credits | Description |
|---|---|---|
POST /api/v1/x/search | 1 | Search tweets and people |
POST /api/v1/x/tweet | 1 | Full details for a single tweet |
POST /api/v1/x/tweet/comments | 1 | Replies to a tweet (ranked or chronological) |
POST /api/v1/x/tweet/retweeters | 1 | Users who retweeted a tweet |
POST /api/v1/x/user | 1 | Profile details for a user |
POST /api/v1/x/user/tweets | 1 | A user's tweets |
POST /api/v1/x/user/replies | 1 | A user's tweets and replies |
POST /api/v1/x/user/media | 1 | A user's media tweets |
POST /api/v1/x/user/followers | 1 | A user's followers |
POST /api/v1/x/user/followings | 1 | Accounts a user follows |
POST /api/v1/x/trending | 1 | Trending topics for a country |
POST /api/v1/x/search/communities | 1 | Search X Communities by keyword |
POST /api/v1/x/community | 1 | One Community's details and rules |
POST /api/v1/x/community/tweets | 1 | Posts in a Community (relevance or recency) |
/x/search with search. Use search_type to switch category (Top, Latest, People, Photos, Videos). Read timeline[].tweet_id./x/tweet with tweet_id for full metrics./x/tweet/comments with tweet_id (set rank: latest for chronological), and /x/tweet/retweeters for who retweeted./x/user with screen_name (a handle without @)./x/user/tweets, /x/user/replies, or /x/user/media with screen_name./x/user/followers and /x/user/followings./x/trending with a country name./x/search/communities with keyword, take a community_id, then /x/community for its details and rules and /x/community/tweets (optional ranking) for its posts.Paginated endpoints return next_cursor (and often prev_cursor); pass next_cursor back as cursor for the next page. Stop when it is null.
/search)| Parameter | Type | Default | Description |
|---|---|---|---|
search | string | required | Search query (1-500 chars) |
search_type | string | Top | Top, Latest, People, Photos, Videos |
cursor | string | -- | Pagination cursor from a prior next_cursor |
/tweet)tweet_id* — a tweet id, e.g. 1808168603721650364.
/tweet/comments)| Parameter | Type | Default | Description |
|---|---|---|---|
tweet_id | string | required | Tweet id |
rank | string | top | top (ranked) or latest (chronological) |
cursor | string | -- | Pagination cursor |
/tweet/retweeters)tweet_id* , cursor (optional).
/user)screen_name* — an X handle without @, e.g. elonmusk.
| Parameter | Type | Default | Description |
|---|---|---|---|
screen_name | string | required | Handle without @ |
cursor | string | -- | Pagination cursor |
/trending)country (optional, default UnitedStates) — a country name.
/search/communities)| Parameter | Type | Default | Description |
|---|---|---|---|
keyword | string | required | Search query (1-500 chars) — this field is keyword, not search |
cursor | string | -- | Pagination cursor |
/community)community_id* — a numeric Community id from /search/communities.
/community/tweets)| Parameter | Type | Default | Description |
|---|---|---|---|
community_id | string | required | Numeric Community id |
ranking | string | -- | Relevance or Recency; omit for the Community's own ordering |
cursor | string | -- | Pagination cursor |
import requests
BASE = "https://api.scavio.dev"
# Your key from https://scavio.dev. Load it from your environment or secret
# store in real code - keep it out of source control.
API_KEY = "sk_your_key_here"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1. Search — use "search", not "query"
results = requests.post(f"{BASE}/api/v1/x/search", headers=HEADERS,
json={"search": "AI agents", "search_type": "Latest"}).json()
tweet_id = results["data"]["timeline"][0]["tweet_id"]
# 2. Full tweet + its replies
tweet = requests.post(f"{BASE}/api/v1/x/tweet", headers=HEADERS,
json={"tweet_id": tweet_id}).json()
comments = requests.post(f"{BASE}/api/v1/x/tweet/comments", headers=HEADERS,
json={"tweet_id": tweet_id, "rank": "latest"}).json()
# 3. A user's recent tweets
user_tweets = requests.post(f"{BASE}/api/v1/x/user/tweets", headers=HEADERS,
json={"screen_name": "elonmusk"}).json()
# 4. Trending in a country
trending = requests.post(f"{BASE}/api/v1/x/trending", headers=HEADERS,
json={"country": "UnitedStates"}).json()
# 5. Find a Community, then read its newest posts
found = requests.post(f"{BASE}/api/v1/x/search/communities", headers=HEADERS,
json={"keyword": "crypto"}).json()
community_id = found["data"]["communities"][0]["community_id"]
posts = requests.post(f"{BASE}/api/v1/x/community/tweets", headers=HEADERS,
json={"community_id": community_id, "ranking": "Recency"}).json()
for p in posts["data"]["timeline"]:
print(p["screen_name"], p["favorites"], p["text"][:80])
Every response uses the envelope { data, response_time, credits_used, credits_remaining }. Key data fields per endpoint:
timeline[] (type, tweet_id, screen_name, text, lang, created_at, favorites, retweets, replies, quotes, bookmarks, views, source), next_cursor, prev_cursor.tweet_id, text, display_text, created_at, lang, favorites, retweets, replies, quotes, bookmarks, views, source, reply_to.timeline[] (tweet_id, screen_name, text, created_at, favorites, ...), next_cursor, prev_cursor.retweeters[] (user_id, screen_name, name, description, followers_count, friends_count, statuses_count, media_count, profile_image), next_cursor.rest_id, screen_name, name, description, followers_count, friends_count, statuses_count, media_count, blue_verified, avatar, header_image, created_at, location, website.pinned (a tweet), timeline[] (tweet_id, text, created_at, favorites, retweets, replies, quotes, views, conversation_id), next_cursor.timeline[] (same tweet item shape), user, next_cursor.timeline[] (same tweet item shape), user, next_cursor.followers_count, followers[] (user_id, screen_name, name, description, followers_count, blue_verified, location), next_cursor.following[] (same user item shape), next_cursor, more_users.trends[] (name, description, context).communities[] (community_id, name, member_count, primary_topic, is_nsfw, banner), next_cursor, has_more.community_id, name, description, created_at, member_count, primary_topic, is_nsfw, banner, rules[] (name, description).timeline[] (same tweet item shape as search, plus author{user_id,name,screen_name,blue_verified} and media{photos[],videos[]}), next_cursor, has_more.{
"data": {
"timeline": [
{
"type": "tweet",
"tweet_id": "1808168603721650364",
"screen_name": "OpenAIDevs",
"text": "Shipping agent tooling this week.",
"lang": "en",
"created_at": "2026-06-30T18:04:11+0000",
"favorites": 4821,
"retweets": 902,
"replies": 311,
"quotes": 77,
"views": 512340,
"source": "Twitter Web App"
}
],
"next_cursor": "DAADDAABCgAB...",
"prev_cursor": "DAABCgABCgAB..."
},
"credits_used": 1,
"credits_remaining": 999
}
search, not query — this differs from some other Scavio endpoints. Community search is the exception: it takes keyword.screen_name is a handle without the leading @.400 means an invalid or missing parameter (e.g. no tweet_id or screen_name) — fix and retry.401 means the API key is invalid or missing. Check SCAVIO_API_KEY.429 means rate or usage limit exceeded. Wait before retrying. See rate limits.502 / 503 mean upstream is temporarily unavailable. Wait a few seconds before retrying.search_type.SCAVIO_API_KEY is not set, prompt the user to export it before continuing.pip install langchain-scavio==4.0.2
from langchain_scavio import ScavioSearchTool
tool = ScavioSearchTool(engine="x")