Skip to main content

User Information

Retrieve detailed user profile information, statistics, and recent activity for specific Twitter/X users.

Endpoint

HTTP Request

GET /x/user/{identifier}
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Path Parameters

identifier

  • Type: String
  • Description: User identifier (username or user ID)
  • Examples: twitter_user, 1234567890

Query Parameters

fields

  • Type: String
  • Description: Comma-separated list of fields to include
  • Options: id, username, name, description, location, url, profile_image_url, protected, verified, created_at, public_metrics, pinned_tweet_id
  • Default: All fields
  • Example: ?fields=id,username,name,public_metrics

include_tweets

  • Type: Boolean
  • Description: Include recent tweets in response
  • Default: false
  • Example: ?include_tweets=true

tweet_count

  • Type: Integer
  • Description: Number of recent tweets to include (if include_tweets=true)
  • Default: 10
  • Maximum: 100
  • Example: ?include_tweets=true&tweet_count=20

Response Format

Success Response (200 OK)

{
  "data": {
    "id": "1234567890123456789",
    "username": "example_user",
    "name": "Example User",
    "description": "Software developer and tech enthusiast",
    "location": "San Francisco, CA",
    "url": "https://example.com",
    "profile_image_url": "https://pbs.twimg.com/profile_images/1234567890/example.jpg",
    "protected": false,
    "verified": true,
    "created_at": "2010-03-15T12:30:00Z",
    "public_metrics": {
      "followers_count": 15420,
      "following_count": 850,
      "tweet_count": 12500,
      "listed_count": 45
    },
    "pinned_tweet_id": "9876543210987654321"
  },
  "includes": {
    "tweets": [
      {
        "id": "9876543210987654321",
        "text": "Just shipped a new feature! #programming #javascript",
        "created_at": "2024-01-15T10:30:00Z",
        "public_metrics": {
          "retweet_count": 25,
          "like_count": 150,
          "reply_count": 12,
          "quote_count": 5
        }
      }
    ]
  },
  "meta": {
    "result_count": 1,
    "request_id": "req_1234567890"
  }
}

Error Response (404 Not Found)

{
  "error": "User not found",
  "code": 404,
  "details": {
    "identifier": "nonexistent_user"
  },
  "timestamp": "2024-01-15T10:30:00Z",
  "requestId": "req_1234567890"
}

Implementation Examples

JavaScript (Node.js)

const axios = require("axios");

async function getUserInfo(apiKey, identifier, options = {}) {
  try {
    const params = new URLSearchParams();

    if (options.fields) params.append("fields", options.fields);
    if (options.includeTweets) params.append("include_tweets", "true");
    if (options.tweetCount) params.append("tweet_count", options.tweetCount);

    const response = await axios.get(`https://api.scrape.st/x/user/${identifier}?${params}`, {
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Content-Type": "application/json",
      },
    });

    const userData = response.data;
    console.log(`Retrieved user data for: ${userData.data.username}`);

    // Analyze user profile
    analyzeUserProfile(userData.data);

    return userData;
  } catch (error) {
    console.error(`Failed to get user info for ${identifier}:`, error.response?.data || error.message);
    throw error;
  }
}

function analyzeUserProfile(user) {
  console.log("\n=== User Profile Analysis ===");
  console.log(`Username: @${user.username}`);
  console.log(`Name: ${user.name}`);
  console.log(`Verified: ${user.verified ? "Yes" : "No"}`);
  console.log(`Account Created: ${new Date(user.created_at).toLocaleDateString()}`);

  const metrics = user.public_metrics;
  console.log(`\nFollowers: ${metrics.followers_count.toLocaleString()}`);
  console.log(`Following: ${metrics.following_count.toLocaleString()}`);
  console.log(`Tweets: ${metrics.tweet_count.toLocaleString()}`);
  console.log(`Listed: ${metrics.listed_count.toLocaleString()}`);

  // Calculate engagement ratio
  const engagementRatio = metrics.followers_count > 0 ? metrics.following_count / metrics.followers_count : 0;
  console.log(`Engagement Ratio: ${engagementRatio.toFixed(3)}`);

  // Account age
  const accountAge = (Date.now() - new Date(user.created_at)) / (1000 * 60 * 60 * 24 * 365);
  console.log(`Account Age: ${accountAge.toFixed(1)} years`);

  // Tweet frequency
  const tweetsPerDay = metrics.tweet_count / (accountAge * 365);
  console.log(`Tweets per Day: ${tweetsPerDay.toFixed(1)}`);
}

// Usage
getUserInfo("your_api_key_here", "twitter_user", {
  includeTweets: true,
  tweetCount: 5,
});

Python

import requests
from datetime import datetime

def get_user_info(api_key, identifier, **options):
    params = {}
    if 'fields' in options:
        params['fields'] = options['fields']
    if 'include_tweets' in options:
        params['include_tweets'] = str(options['include_tweets']).lower()
    if 'tweet_count' in options:
        params['tweet_count'] = options['tweet_count']

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    try:
        response = requests.get(f"https://api.scrape.st/x/user/{identifier}",
                             params=params, headers=headers)
        response.raise_for_status()
        user_data = response.json()

        print(f"Retrieved user data for: {user_data['data']['username']}")

        # Analyze user profile
        analyze_user_profile(user_data['data'])

        return user_data
    except requests.exceptions.RequestException as error:
        print(f"Failed to get user info for {identifier}: {error}")
        if error.response:
            print(f"Error details: {error.response.text}")
        raise

def analyze_user_profile(user):
    print("\n=== User Profile Analysis ===")
    print(f"Username: @{user['username']}")
    print(f"Name: {user['name']}")
    print(f"Verified: {'Yes' if user['verified'] else 'No'}")
    print(f"Account Created: {datetime.fromisoformat(user['created_at'].replace('Z', '+00:00')).strftime('%Y-%m-%d')}")

    metrics = user['public_metrics']
    print(f"\nFollowers: {metrics['followers_count']:,}")
    print(f"Following: {metrics['following_count']:,}")
    print(f"Tweets: {metrics['tweet_count']:,}")
    print(f"Listed: {metrics['listed_count']:,}")

    # Calculate engagement ratio
    engagement_ratio = metrics['following_count'] / metrics['followers_count'] if metrics['followers_count'] > 0 else 0
    print(f"Engagement Ratio: {engagement_ratio:.3f}")

    # Account age
    account_age = (datetime.now() - datetime.fromisoformat(user['created_at'].replace('Z', '+00:00'))).days / 365
    print(f"Account Age: {account_age:.1f} years")

    # Tweet frequency
    tweets_per_day = metrics['tweet_count'] / (account_age * 365)
    print(f"Tweets per Day: {tweets_per_day:.1f}")

# Usage
get_user_info("your_api_key_here", "twitter_user",
             include_tweets=True, tweet_count=5)

cURL

# Get basic user information
curl -X GET "https://api.scrape.st/x/user/twitter_user" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# Get user information with recent tweets
curl -X GET "https://api.scrape.st/x/user/twitter_user?include_tweets=true&tweet_count=10" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# Get specific fields only
curl -X GET "https://api.scrape.st/x/user/twitter_user?fields=id,username,name,public_metrics" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Advanced Usage

Batch User Lookup

async function getMultipleUsers(apiKey, usernames) {
  const results = [];

  for (const username of usernames) {
    try {
      const userData = await getUserInfo(apiKey, username);
      results.push({ username, status: "success", data: userData.data });
    } catch (error) {
      results.push({ username, status: "error", error: error.message });
    }
  }

  return results;
}

// Usage
const usernames = ["user1", "user2", "user3"];
const userResults = await getMultipleUsers("your_api_key_here", usernames);

console.log("User Lookup Results:");
userResults.forEach((result) => {
  const status = result.status === "success" ? "success" : "failed";
  console.log(`${status}: ${result.username}`);
});

User Comparison

function compareUsers(user1, user2) {
  const comparison = {
    followers: {
      user1: user1.public_metrics.followers_count,
      user2: user2.public_metrics.followers_count,
      winner:
        user1.public_metrics.followers_count > user2.public_metrics.followers_count ? user1.username : user2.username,
    },
    tweets: {
      user1: user1.public_metrics.tweet_count,
      user2: user2.public_metrics.tweet_count,
      winner: user1.public_metrics.tweet_count > user2.public_metrics.tweet_count ? user1.username : user2.username,
    },
    engagement: {
      user1: calculateEngagement(user1),
      user2: calculateEngagement(user2),
      winner: null,
    },
  };

  comparison.engagement.winner =
    comparison.engagement.user1 > comparison.engagement.user2 ? user1.username : user2.username;

  return comparison;
}

function calculateEngagement(user) {
  const followers = user.public_metrics.followers_count;
  const following = user.public_metrics.following_count;
  return followers > 0 ? following / followers : 0;
}

// Usage
const userData1 = await getUserInfo(apiKey, "user1");
const userData2 = await getUserInfo(apiKey, "user2");
const comparison = compareUsers(userData1.data, userData2.data);

console.log("User Comparison:");
console.log(`Followers Winner: ${comparison.followers.winner}`);
console.log(`Tweets Winner: ${comparison.tweets.winner}`);
console.log(`Engagement Winner: ${comparison.engagement.winner}`);

Error Handling

Common Error Responses

404 Not Found

{
  "error": "User not found",
  "code": 404,
  "details": {
    "identifier": "nonexistent_user"
  }
}

401 Unauthorized

{
  "error": "Invalid API key",
  "code": 401
}

429 Too Many Requests

{
  "error": "Rate limit exceeded",
  "code": 429,
  "retryAfter": 900
}

Error Handling Implementation

async function getUserInfoWithRetry(apiKey, identifier, options = {}, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await getUserInfo(apiKey, identifier, options);
    } catch (error) {
      if (error.response?.status === 429) {
        const retryAfter = error.response.data?.retryAfter || 900;
        console.log(`Rate limited, retrying in ${retryAfter} seconds...`);
        await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      if (error.response?.status === 404) {
        throw new Error(`User ${identifier} not found`);
      }

      if (error.response?.status === 401) {
        throw new Error("Invalid API key");
      }

      if (attempt === maxRetries) {
        throw error;
      }

      const delay = Math.pow(2, attempt) * 1000;
      console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }
}

Data Analysis

User Metrics Analysis

function analyzeUserMetrics(user) {
  const metrics = user.public_metrics;
  const analysis = {
    influence: {
      level: calculateInfluenceLevel(metrics.followers_count),
      score: calculateInfluenceScore(metrics),
    },
    activity: {
      level: calculateActivityLevel(metrics.tweet_count, user.created_at),
      score: calculateActivityScore(metrics, user.created_at),
    },
    engagement: {
      ratio: calculateEngagementRatio(metrics),
      quality: assessEngagementQuality(metrics),
    },
  };

  return analysis;
}

function calculateInfluenceLevel(followers) {
  if (followers >= 1000000) return "celebrity";
  if (followers >= 100000) return "influencer";
  if (followers >= 10000) return "micro_influencer";
  if (followers >= 1000) return "active";
  return "casual";
}

function calculateInfluenceScore(metrics) {
  const followersScore = Math.log10(metrics.followers_count + 1) * 20;
  const listedScore = metrics.listed_count * 5;
  const verifiedScore = metrics.verified ? 25 : 0;

  return Math.min(100, followersScore + listedScore + verifiedScore);
}

function calculateActivityLevel(tweetCount, createdAt) {
  const accountAge = (Date.now() - new Date(createdAt)) / (1000 * 60 * 60 * 24 * 365);
  const tweetsPerYear = tweetCount / accountAge;

  if (tweetsPerYear >= 1000) return "hyper_active";
  if (tweetsPerYear >= 500) return "very_active";
  if (tweetsPerYear >= 100) return "active";
  if (tweetsPerYear >= 50) return "moderate";
  return "occasional";
}

function calculateActivityScore(metrics, createdAt) {
  const accountAge = (Date.now() - new Date(createdAt)) / (1000 * 60 * 60 * 24 * 365);
  const tweetsPerYear = metrics.tweet_count / accountAge;

  return Math.min(100, Math.log10(tweetsPerYear + 1) * 25);
}

function calculateEngagementRatio(metrics) {
  return metrics.followers_count > 0 ? metrics.following_count / metrics.followers_count : 0;
}

function assessEngagementQuality(metrics) {
  const ratio = calculateEngagementRatio(metrics);
  if (ratio > 0.1) return "high";
  if (ratio > 0.05) return "medium";
  if (ratio > 0.01) return "low";
  return "minimal";
}

Best Practices

For Efficient Queries

  • Specific Fields: Request only the fields you need
  • Batch Processing: Process multiple users together when possible
  • Caching: Cache user data to reduce API calls
  • Rate Limiting: Implement rate limiting for batch operations

For Data Management

  • Data Validation: Validate user data before processing
  • Error Handling: Handle user not found and rate limit errors
  • Storage Planning: Plan appropriate storage for user data
  • Privacy Compliance: Respect user privacy and data protection

For Analysis

  • Context Analysis: Consider user context when analyzing metrics
  • Comparative Analysis: Compare users relative to their peers
  • Temporal Analysis: Consider account age and activity patterns
  • Quality Assessment: Assess data quality and completeness
Next: Tweet Data