Skip to content

Users ​

Get user profiles, follow, block, mute, manage relationships, and fetch user content.

users.get(userId) ​

Get a user by their REST ID. Uses the GraphQL UserByRestId query.

js
const user = await client.users.get("44196397");
console.log(user.name); // "Elon Musk"
console.log(user.username); // "elonmusk"

Returns: Parsed user object.

users.getByUsername(username) ​

Get a user by their screen name. Uses the GraphQL UserByScreenName query.

js
const user = await client.users.getByUsername("elonmusk");
console.log(user.id);
console.log(user.stats.followers.count);

Returns: Parsed user object.

users.getMany(userIds) ​

Get multiple users by their REST IDs. Uses the GraphQL UsersByRestIds query.

js
const users = await client.users.getMany(["44196397", "12"]);
users.forEach((u) => console.log(u.username));

Returns: Array of parsed user objects.

users.getManyByUsername(screenNames) ​

Get multiple users by their screen names. Uses the GraphQL UsersByScreenNames query.

js
const users = await client.users.getManyByUsername(["elonmusk", "jack"]);
users.forEach((u) => console.log(u.id));

Returns: Array of parsed user objects.

User content ​

Fetch a user's tweets, replies, media, and highlights.

users.tweets(userId, opts?) ​

Get a user's tweets. Uses the GraphQL UserTweets query.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets, nextCursor } = await client.users.tweets("44196397");
console.log(tweets[0].text);

// Paginate
const page2 = await client.users.tweets("44196397", { cursor: nextCursor });

users.replies(userId, opts?) ​

Get a user's tweets and replies. Uses the GraphQL UserTweetsAndReplies query.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.replies("44196397");

users.userMedia(userId, opts?) ​

Get a user's media tweets. Uses the GraphQL UserMedia query.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.userMedia("44196397", { count: 40 });

users.highlights(userId, opts?) ​

Get a user's highlighted tweets. Uses the GraphQL UserHighlightsTweets query.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.highlights("44196397");

Get a user's original posts, most liked first. This is the "Popular" sort on x.com profiles. Uses the GraphQL UserOriginalsTimeline query with sortByMostLiked. Replies and reposts are left out, and a pinned post still comes first.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.popular("44196397");

UserTweets accepts sortByMostLiked too but ignores it, so use this method instead.

users.originals(userId, opts?) ​

Get a user's original posts, newest first. Uses the same GraphQL UserOriginalsTimeline query as users.popular with sortByMostLiked: false. Reposts are left out, and a pinned post still comes first.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets, nextCursor } = await client.users.originals("44196397");

users.reposts(userId, opts?) ​

Get only the posts a user reposted, newest first. Uses the GraphQL UserRepostsTimeline query. Each entry is the repost wrapper, so read the original from its retweeted_status.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets, nextCursor } = await client.users.reposts("783214");

Twitter fills pages to about 20 entries whatever count you pass.

users.videos(userId, opts?) ​

Get a user's posts that have a native video, newest first. Uses the GraphQL UserVideoTimeline query, the same one behind the videos filter on x.com profiles.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.videos("44196397");

users.photos(userId, opts?) ​

Get a user's posts that have photos, newest first. Uses the GraphQL UserPhotoTimeline query.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.photos("44196397");

users.repliesOnly(userId, opts?) ​

Get a user's replies, which is the "Replies" tab on x.com profiles. Uses the GraphQL UserRepliesTimeline query. users.replies uses UserTweetsAndReplies and mixes in the user's own posts. This one returns reply threads instead: each reply comes with the post it answers, so not every tweet in the page is by the user.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.repliesOnly("2244994945");
const own = tweets.filter((tweet) => tweet.user?.id === "2244994945");

users.superFollowTweets(userId, opts?) ​

Get a user's subscriber only posts. Uses the GraphQL UserSuperFollowTweets query. The timeline is empty unless you subscribe to that user.

OptionTypeDescription
userIdstringThe user's REST ID
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { tweets } = await client.users.superFollowTweets("44196397");

users.affiliates(userId, opts?) ​

Get the accounts affiliated with a business profile, such as the accounts under @X. Uses the GraphQL UserBusinessProfileTeamTimeline query, the one behind the "Affiliates" tab. The result has users and no tweets.

OptionTypeDescription
userIdstringThe business account's REST ID
opts.teamNamestringTeam to list (default "NotAssigned", all)
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { users } = await client.users.affiliates("783214");

users.verifiedAvatars(userIds) ​

Get the verification type, affiliate badge and avatar shape of several users in one request. Uses the GraphQL UsersVerifiedAvatars query, which x.com runs for the account switcher.

OptionTypeDescription
userIdsstring | string[]One or more REST IDs
js
const avatars = await client.users.verifiedAvatars(["2244994945", "44196397"]);
// [{ id: "2244994945", verified: true, verified_type: "Business", label: { ... }, imageShape: "Square", raw: { ... } }, ...]

verified and verified_type follow the same rules as user.verification.

users.sidebarRecommendations(userId) ​

Get the "You might like" accounts x.com shows next to a profile. Uses the GraphQL SidebarUserRecommendations query. Each entry has a token and a parsed user.

OptionTypeDescription
userIdstringREST ID of the profile you view
js
const recs = await client.users.sidebarRecommendations("44196397");
console.log(recs.map(({ user }) => user.username));

users.about(username) ​

Get the "About this account" data x.com shows on profiles. Uses the GraphQL AboutAccountQuery query. Twitter rate limits it to 50 calls per 15 minutes, so cache the result.

js
const about = await client.users.about("elonmusk");
// {
//   id: "44196397",
//   username: "elonmusk",
//   basedIn: "United States",
//   locationAccurate: true,
//   source: "United States App Store",
//   usernameChanges: 0,
//   lastUsernameChange: null,
//   verifiedSince: -156836000000000,
//   identityVerified: false,
//   affiliate: "X",
//   raw: { ... }
// }
FieldTypeDescription
basedInstring | nullCountry or region the account is based in, as an English name
locationAccuratebooleanfalse when Twitter thinks the location comes from a VPN or proxy
sourcestring | nullWhere the account connects from, e.g. "Portugal App Store"
usernameChangesnumberHow many times the username changed
lastUsernameChangenumber | nullTimestamp in milliseconds of the last change
verifiedSincenumber | nullTimestamp in milliseconds. Some accounts have joke values far in the past
identityVerifiedbooleanWhether the account passed ID verification
affiliatestring | nullUsername of the affiliated organization
rawobjectThe unparsed user result

Profile spotlights ​

Professional accounts can pin cards under their bio, which x.com calls spotlights. The one most people have seen is the location card, with the address, a small map, opening hours and the "Get directions" and "Contact" buttons.

users.locationSpotlight(username) ​

Get the location and contact card of a profile. Returns null when the profile has no location card. Uses the GraphQL ProfileSpotlightsQuery query.

js
const card = await client.users.locationSpotlight("WTechnicians");
// {
//   address: "11483 olive blvd Creve Coeur Missouri 63141",
//   directions_url: "https://www.google.com/maps/search/?api=1&query=11483%20olive%20blvd%20...",
//   map_image: "https://maps.googleapis.com/maps/api/staticmap?...",
//   phone: { country_code: "+1", number: "3145138455", full: "+13145138455" },
//   email: null,
//   website: { url: "https://t.co/aQXV6X09b3", display: "https://watchtechnicians.com/creve-coeur/" },
//   hours: { type: null, is_open: null, opens: null, closes: null },
//   contact: { call: true, sms: true, dm: true, email: false },
// }
FieldTypeDescription
addressstring | nullThe address as the owner typed it. x.com does not check it, so it can be any text
directions_urlstring | nullThe Google Maps link the "Get directions" button opens
map_imagestring | nullThe static map x.com shows. Only present when Google matched the address
phoneobject | nullcountry_code, number and full, which is the two joined
emailstring | nullContact email
websiteobject | nullurl is the t.co link and display is the real address
hoursobjecttype is "AlwaysOpen" or "RegularHours", is_open is the state right now, opens and closes are the next change as { day, hour, minute }
contactobjectWhich entries the "Contact" menu has: call, sms, dm and email

The phone number and email are only included when the owner turned them on in the "Contact" menu.

users.spotlights(username) ​

Get every spotlight on a profile in one request. Spotlights the profile doesn't have are null.

js
const { location, shop, jobs, communities } = await client.users.spotlights("SpaceX");
// jobs: [{ id: "2101416365848743937", title: "Sr. Spaceport Designer, Interior Design", location: "Starbase, TX", url: "https://boards.greenhouse.io/...", salary: null }, ...]

const { shop: products } = await client.users.spotlights("Google");
// [{ id: "1958256902653333836", title: "Pixel 10 Indigo 128GB (Unlocked)", url: "https://t.co/...", image: "https://pbs.twimg.com/commerce_product_img/...", price: { currency: "Usd", amount: 799 } }, ...]
FieldTypeDescription
id, usernamestringThe profile
verified_organizationbooleantrue for accounts with a gold check
locationobject | nullSame as users.locationSpotlight
shopobject[] | nullProducts from the Shop Spotlight. price.amount is in whole units
jobsobject[] | nullFeatured jobs from the Jobs Spotlight
communitiesobject | nullThe pinned community, unparsed
modulesobject[]Every module as x.com sent it
rawobjectThe unparsed response

Relationships ​

users.followers(userId, opts?) ​

Get a user's followers. Uses the GraphQL Followers query.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users, nextCursor } = await client.users.followers("44196397", {
  count: 50,
});

users.following(userId, opts?) ​

Get users that a user is following. Uses the GraphQL Following query.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users } = await client.users.following("44196397");

users.verifiedFollowers(userId, opts?) ​

Get a user's verified (Blue) followers. Uses the GraphQL BlueVerifiedFollowers query.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users } = await client.users.verifiedFollowers("44196397");

users.followersYouKnow(userId, opts?) ​

Get followers of a user that you also follow. Uses the GraphQL FollowersYouKnow query.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users } = await client.users.followersYouKnow("44196397");

users.follow(userId) ​

Follow a user. Uses the v1.1 friendships/create endpoint.

js
const user = await client.users.follow("44196397");
console.log(user.username); // "elonmusk"

Returns: Parsed user object.

users.unfollow(userId) ​

Unfollow a user. Uses the v1.1 friendships/destroy endpoint.

js
await client.users.unfollow("44196397");

Returns: Parsed user object.

users.block(userId) ​

Block a user. Uses the v1.1 blocks/create endpoint.

js
await client.users.block("44196397");

Returns: Parsed user object.

users.unblock(userId) ​

Unblock a user. Uses the v1.1 blocks/destroy endpoint.

js
await client.users.unblock("44196397");

Returns: Parsed user object.

users.mute(userId) ​

Mute a user. Uses the v1.1 mutes/users/create endpoint.

js
await client.users.mute("44196397");

Returns: Parsed user object.

users.unmute(userId) ​

Unmute a user. Uses the v1.1 mutes/users/destroy endpoint.

js
await client.users.unmute("44196397");

Returns: Parsed user object.

users.report(userId, reason, opts?) ​

Report a user account for a policy violation. Alias for report.user.

js
await client.users.report("44196397", "spam");

users.removeFollower(userId) ​

Remove a user from your followers. Uses the GraphQL RemoveFollower mutation.

js
await client.users.removeFollower("44196397");

users.blocked(opts?) ​

Get all accounts you have blocked. Uses the GraphQL BlockedAccountsAll query.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users } = await client.users.blocked({ count: 100 });

users.muted(opts?) ​

Get all accounts you have muted. Uses the GraphQL MutedAccounts query.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users } = await client.users.muted();

Profile management ​

users.lookup(params?) ​

Look up users via the v1.1 users/lookup endpoint. Supports lookup by user_id or screen_name.

js
// By user IDs
const users = await client.users.lookup({ user_id: "44196397,12" });

// By screen names
const users = await client.users.lookup({ screen_name: "elonmusk,jack" });

users.updateProfile(params?) ​

Update your profile. Uses the v1.1 account/update_profile endpoint.

ParamTypeDescription
namestringDisplay name
descriptionstringBio
locationstringLocation
urlstringWebsite URL
js
const updated = await client.users.updateProfile({
  name: "New Name",
  description: "Updated bio",
  location: "San Francisco, CA",
  url: "https://example.com",
});

Returns: Parsed user object.

users.updateProfileImage(imageData) ​

Update your profile picture. Uses the v1.1 account/update_profile_image endpoint.

js
await client.users.updateProfileImage(base64ImageData);

users.updateProfileBanner(bannerData) ​

Update your profile banner. Uses the v1.1 account/update_profile_banner endpoint.

js
await client.users.updateProfileBanner(base64BannerData);

users.removeProfileBanner() ​

Remove your profile banner. Uses the v1.1 account/remove_profile_banner endpoint.

js
await client.users.removeProfileBanner();

Subscriptions ​

Subscriptions are the paid monthly memberships creators sell on x.com. Super Follows was the old name for the same thing.

users.subscriptions(userId, opts?) ​

Get the creators a user pays a subscription to. Uses the GraphQL UserCreatorSubscriptions query. The creators are in users.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { users, nextCursor } = await client.users.subscriptions("2387981");

Accounts can hide this list. x.com still returns the count in user.stats.subscriptions_count, but the timeline comes back empty. Check user.stats.subscriptions_hidden first:

js
const user = await client.users.getByUsername("elonmusk");
console.log(user.stats.subscriptions_count); // 253
console.log(user.stats.subscriptions_hidden); // true, so users.subscriptions() returns no users

users.subscribers(userId, opts?) ​

Get the people subscribed to a creator. Uses the GraphQL UserCreatorSubscribers query. x.com only returns them for your own account, any other ID gives an empty timeline.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.variablesobjectAdditional GraphQL variables
js
const { users } = await client.users.subscribers(client.user.id);

users.superFollowers(opts?) ​

Get the people who subscribe to you. Uses the GraphQL SuperFollowers query, which x.com kept from when subscriptions were called Super Follows. It only works for your own account.

OptionTypeDescription
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
js
const { users } = await client.users.superFollowers();

users.recommendations(params?) ​

Get user recommendations. Uses the v1.1 users/recommendations endpoint.

js
const recs = await client.users.recommendations();

Paginated response format ​

All paginated methods (tweets, replies, media, highlights, followers, following, blocked, muted, etc.) return:

js
{
  tweets: [ /* parsed tweet objects */ ],
  users: [ /* parsed user objects */ ],
  nextCursor: "DAABCgAB...",
  previousCursor: "DAABCgAA...",
  raw: { /* original Twitter response */ },
}

Content methods populate tweets, relationship methods populate users. Pass nextCursor as opts.cursor to fetch the next page.

User schema ​

All methods that return users parse them into a consistent format:

js
{
  id: "44196397",
  name: "Elon Musk",
  username: "elonmusk",
  description: "...",
  banner: "https://pbs.twimg.com/...",
  url: "https://t.co/...",
  location: "Earth",
  protected: false,
  created_at: "Tue Jun 02 20:12:29 +0000 2009",
  backgroundColor: "...",
  profile_picture: {
    url: "https://pbs.twimg.com/...",
    shape: "Circle",
  },
  stats: {
    followers: {
      count: 200000000,
      fast_followers: 0,
      normal_followers: 200000000,
    },
    following: 900,
    subscriptions_count: 253,
    subscriptions_hidden: true,
    likes: 50000,
    listed: 150000,
    media: 2000,
    posts: 40000,
  },
  verification: {
    verified: true,
    verified_type: "Premium",
  },
  professional: {
    type: "Creator",
    categories: [],
  },
  pinned_tweets: ["1234567890"],
  birthdate: {},
  labels: {
    parody_commentary_fan_label: "None",
    highlightedLabel: undefined,
  },
  misc: { ... },
}

Verification ​

verification.verified is true for any check mark. verification.verified_type says which one:

verified_typeCheck mark
"Premium"Blue, from an X Premium subscription
"Business"Gold, for Verified Organizations and their affiliates
"Government"Gray, for governments and multilateral organizations
"Legacy"A pre-2023 verification that the response still flags
nullNo check mark, verified is false

An organization with a gold check also pays for Premium, so x.com sends both flags. emusks reports the more specific type, "Business" or "Government".

Subscription count ​

stats.subscriptions_count is how many creators the user subscribes to. Twitter only sends it with full profile lookups such as users.get and users.getByUsername. Users embedded in tweets, timelines and follower lists don't have it, and emusks reports null for them instead of 0. Fetch the user directly if you need the number.

stats.subscriptions_hidden is true when the user hides the list. See users.subscriptions.

not affiliated with X Corp.