← Back to blog
•by Engineering
tutorialbatchanalytics
Batch Operations: Analyze 100 Users in One Call
Why Batch Operations?
When building analytics dashboards or monitoring multiple accounts, making individual API calls for each user is slow and wasteful. XCROP's batch endpoints let you look up 100 users or 100 tweets in a single request — dramatically reducing latency and simplifying your code.
Batch User Lookup
Basic Request
PYTHON
import requests import os response = requests.post( "https://xcrop.io/api/v2/users/batch", headers={ "Authorization": "Bearer " + os.environ["XCROP_API_KEY"], "Content-Type": "application/json" }, json={ "usernames": [ "VitalikButerin", "caboronft", "CryptoHayes", "DefiIgnas", "Pentosh1" ] } ) users = response.json()["data"] for user in users: print("@" + user["username"]) print(" Followers: " + str(user["followers"])) print(" Following: " + str(user["following"])) print(" Tweets: " + str(user["tweets_count"])) print()
Response Format
Each user in the batch response follows the standard user object:
JSON
{ "data": [ { "id": "123456789", "username": "VitalikButerin", "name": "vitalik.eth", "description": "Ethereum co-founder...", "followers": 5400000, "following": 800, "tweets_count": 12000, "listed": 45000, "verified": false, "profile_image": "https://pbs.twimg.com/...", "created_at": "Mon Jun 15 18:01:37 +0000 2013" } ], "meta": { "total": 5, "latency_ms": 320 } }
Limits
• Maximum 100 usernames per batch request
• Costs 18 credits per user returned
• For larger sets, split into multiple batch calls
Batch Tweet Lookup
Similarly, look up multiple tweets by ID in one call:
JAVASCRIPT
const response = await fetch("https://xcrop.io/api/v2/tweets/batch", { method: "POST", headers: { "Authorization": "Bearer " + apiKey, "Content-Type": "application/json" }, body: JSON.stringify({ ids: [ "1234567890123456789", "9876543210987654321", "5555555555555555555" ] }) }); const { data: tweets } = await response.json(); tweets.forEach(tweet => { console.log("@" + tweet.author.username + ": " + tweet.text.slice(0, 80)); console.log(" Likes: " + tweet.metrics.likes + " | RT: " + tweet.metrics.retweets); });
• Maximum 100 tweet IDs per batch request
• Costs 15 credits per tweet returned
Building a KOL Analytics Dashboard
Here's a complete example that fetches multiple KOL profiles, compares their metrics, and ranks them:
PYTHON
import requests import os API_KEY = os.environ["XCROP_API_KEY"] HEADERS = { "Authorization": "Bearer " + API_KEY, "Content-Type": "application/json" } BASE_URL = "https://xcrop.io/api/v2" # Define KOLs to track KOLS = [ "VitalikButerin", "CryptoHayes", "DefiIgnas", "Pentosh1", "inversebrah", "MustStopMurad", "colocobot", "blknoiz06", "GiganticRebirth", "EmberCN" ] def fetch_kol_profiles(usernames): """Batch fetch KOL profiles.""" response = requests.post( BASE_URL + "/users/batch", headers=HEADERS, json={"usernames": usernames} ) return response.json()["data"] def get_recent_tweets(username, count=20): """Fetch recent tweets for engagement analysis.""" response = requests.get( BASE_URL + "/users/" + username + "/tweets", headers=HEADERS, params={"count": count, "sort": "latest"} ) return response.json()["data"] def calculate_engagement_rate(tweets, followers): """Calculate average engagement rate from recent tweets.""" if not tweets or followers == 0: return 0 total_engagement = 0 for tweet in tweets: m = tweet["metrics"] total_engagement += m["likes"] + m["retweets"] + m["replies"] avg_engagement = total_engagement / len(tweets) return round(avg_engagement / followers * 100, 4) # Step 1: Batch fetch all KOL profiles print("Fetching " + str(len(KOLS)) + " KOL profiles...") profiles = fetch_kol_profiles(KOLS) # Step 2: Calculate engagement rates results = [] for profile in profiles: username = profile["username"] tweets = get_recent_tweets(username, count=10) eng_rate = calculate_engagement_rate(tweets, profile["followers"]) results.append({ "username": username, "followers": profile["followers"], "tweets_count": profile["tweets_count"], "engagement_rate": eng_rate }) # Step 3: Rank by engagement rate results.sort(key=lambda x: x["engagement_rate"], reverse=True) print("\n=== KOL Rankings by Engagement Rate ===") for i, kol in enumerate(results): rank = str(i + 1) print(rank + ". @" + kol["username"]) followers_k = str(round(kol["followers"] / 1000)) print(" Followers: " + followers_k + "K") print(" Engagement rate: " + str(kol["engagement_rate"]) + "%") print()
Tracking Follower Growth Over Time
Combine batch lookups with periodic polling to track follower changes:
PYTHON
import requests import time import json import os API_KEY = os.environ["XCROP_API_KEY"] HEADERS = { "Authorization": "Bearer " + API_KEY, "Content-Type": "application/json" } BASE_URL = "https://xcrop.io/api/v2" TRACKED_USERS = ["VitalikButerin", "CryptoHayes", "DefiIgnas"] HISTORY_FILE = "follower_history.json" def load_history(): try: with open(HISTORY_FILE, "r") as f: return json.load(f) except FileNotFoundError: return {} def save_history(history): with open(HISTORY_FILE, "w") as f: json.dump(history, f, indent=2) def snapshot_followers(): """Take a snapshot of follower counts.""" response = requests.post( BASE_URL + "/users/batch", headers=HEADERS, json={"usernames": TRACKED_USERS} ) if response.status_code != 200: print("Error: " + str(response.status_code)) return users = response.json()["data"] history = load_history() timestamp = time.strftime("%Y-%m-%d %H:%M") for user in users: username = user["username"] followers = user["followers"] if username not in history: history[username] = [] prev = history[username][-1]["followers"] if history[username] else followers change = followers - prev history[username].append({ "timestamp": timestamp, "followers": followers, "change": change }) sign = "+" if change >= 0 else "" print("@" + username + ": " + str(followers) + " (" + sign + str(change) + ")") save_history(history) # Run snapshot every hour print("Tracking follower growth...") while True: snapshot_followers() time.sleep(3600) # Check every hour
Comparing Users with Search
Find and compare users matching specific criteria using the user search endpoint:
PYTHON
# Search for DeFi-focused accounts response = requests.post( BASE_URL + "/search/users", headers=HEADERS, json={ "query": "DeFi analyst", "count": 20, "sort": "followers" } ) users = response.json()["data"] print("Top DeFi analysts by followers:") for user in users[:10]: followers_k = str(round(user["followers"] / 1000)) print(" @" + user["username"] + " — " + followers_k + "K followers")
Best Practices
1. Batch whenever possible — 1 batch call for 100 users beats 100 individual calls
2. Cache profiles — User profiles are cached for 5 minutes; don't re-fetch more often
3. Use sort parameters — Sort followers by
followers count to find the most influential ones first4. Combine batch + timeline — Fetch profiles in batch, then get tweets for top accounts only
5. Mind the credits — Batch user lookup costs 18 credits/user; 100 users = 1,800 credits per call
Credit Usage
• Batch user lookup: 18 credits per user (max 100 per call)
• Batch tweet lookup: 15 credits per tweet (max 100 per call)
• User tweets: 15 credits per tweet returned
• User search: 18 credits per user returned
• 100-user batch = 1,800 credits — with Pro plan ($9.9/mo, 2M credits) you can do ~1,100 batch calls/month