Official Node.js/TypeScript SDK for TweetAPI — the Twitter/X Data API for developers and researchers.
Access tweets, user profiles, followers, analytics, and full interaction capabilities. 70+ typed endpoints with built-in error handling.
npm install tweetapi-nodeimport TweetAPI from "tweetapi-node";
const client = new TweetAPI({ apiKey: "YOUR_API_KEY" });
// Get a user profile
const user = await client.user.getByUsername({ username: "elonmusk" });
console.log(user.data.followerCount); // 180000000
// Search tweets
const results = await client.explore.search({ query: "bitcoin", type: "Latest" });
// Get followers with pagination
const followers = await client.user.getFollowers({ userId: "123456" });
const nextPage = await client.user.getFollowers({
userId: "123456",
cursor: followers.pagination.nextCursor!,
});Get your free API key — 100 requests, no credit card required
- 70+ endpoints covering users, tweets, posts, interactions, DMs, communities, spaces, and search
- Full TypeScript types for all requests and responses — autocomplete everything
- Automatic retry with backoff on rate limits (429) and server errors (5xx)
- Auto-pagination helpers — iterate all pages with
for await...of - Solid error handling with typed exceptions (
RateLimitError,NotFoundError, etc.) - Rate limit awareness —
retryAfterrespected automatically, state exposed viaclient.rateLimitInfo - Zero dependencies — uses native
fetch(Node.js 18+) - ESM and CommonJS dual build
| Method | Description |
|---|---|
client.user.getByUsername({ username }) |
Get user profile by username |
client.user.getByUsernames({ usernames }) |
Get multiple users by usernames (comma-separated) |
client.user.getByUserId({ userId }) |
Get user profile by ID |
client.user.getByUserIds({ userIds }) |
Get multiple users by IDs (comma-separated) |
client.user.getTweets({ userId }) |
Get a user's tweets |
client.user.getTweetsAndReplies({ userId }) |
Get a user's tweets and replies |
client.user.getFollowing({ userId }) |
Get who a user follows |
client.user.getFollowers({ userId }) |
Get a user's followers |
client.user.getVerifiedFollowers({ userId }) |
Get verified followers |
client.user.getSubscriptions({ userId }) |
Get user's subscriptions |
client.user.getFollowingV1({ userId }) |
Get following (v1, supports count) |
client.user.getFollowersV1({ userId }) |
Get followers (v1, supports count) |
client.user.getFollowingIds({ userId }) |
Get following user IDs |
client.user.getFollowersIds({ userId }) |
Get follower user IDs |
client.user.checkFollow({ subjectId, targetId }) |
Check follow relationship |
client.user.aboutAccount({ username }) |
Get account transparency info |
| Method | Description |
|---|---|
client.tweet.getDetailsAndConversation({ tweetId }) |
Get tweet details and replies |
client.tweet.getDetailsByIds({ ids }) |
Get multiple tweets by IDs (max 200) |
client.tweet.getRetweets({ tweetId }) |
Get who retweeted a tweet |
client.tweet.getQuotes({ tweetId }) |
Get quote tweets |
client.tweet.translate({ tweetId, dstLang }) |
Translate a tweet |
| Method | Description |
|---|---|
client.post.createPost({ authToken, text, proxy }) |
Create a tweet |
client.post.createPostQuote({ authToken, text, attachmentUrl, proxy }) |
Create a quote tweet |
client.post.createPostWithMedia({ authToken, text, media, proxy }) |
Create a tweet with media |
client.post.replyPost({ authToken, text, tweetId, proxy }) |
Reply to a tweet |
client.post.replyPostWithMedia({ authToken, text, tweetId, media, proxy }) |
Reply with media |
client.post.deletePost({ authToken, tweetId }) |
Delete a tweet |
| Method | Description |
|---|---|
client.interaction.favoritePost({ authToken, tweetId }) |
Like a tweet |
client.interaction.unfavoritePost({ authToken, tweetId }) |
Unlike a tweet |
client.interaction.retweet({ authToken, tweetId }) |
Retweet |
client.interaction.deleteRetweet({ authToken, tweetId }) |
Remove retweet |
client.interaction.bookmark({ authToken, tweetId }) |
Bookmark a tweet |
client.interaction.deleteBookmark({ authToken, tweetId }) |
Remove bookmark |
client.interaction.follow({ authToken, userId }) |
Follow a user |
client.interaction.unfollow({ authToken, userId }) |
Unfollow a user |
client.interaction.addMemberToList({ authToken, listId, userId }) |
Add user to list |
client.interaction.removeMemberFromList({ authToken, listId, userId }) |
Remove user from list |
client.interaction.getNotifications({ authToken }) |
Get notifications |
client.interaction.getUserAnalytics({ authToken }) |
Get account analytics |
| Method | Description |
|---|---|
client.list.getDetails({ listId }) |
Get list details |
client.list.getTweets({ listId }) |
Get tweets in a list |
client.list.getMembers({ listId }) |
Get list members |
client.list.getFollowers({ listId }) |
Get list followers |
| Method | Description |
|---|---|
client.community.getDetails({ communityId }) |
Get community details |
client.community.getTweets({ communityId, sortBy }) |
Get community tweets |
client.community.getMembers({ communityId }) |
Get community members |
client.community.search({ query }) |
Search communities |
client.community.createPost({ authToken, text, communityId, proxy }) |
Post in community |
client.community.createPostWithMedia({ ... }) |
Post with media in community |
client.community.replyPost({ ... }) |
Reply to community post |
client.community.replyPostWithMedia({ ... }) |
Reply with media in community |
client.community.join({ authToken, communityId }) |
Join a community |
client.community.leave({ authToken, communityId }) |
Leave a community |
| Method | Description |
|---|---|
client.space.getById({ spaceId }) |
Get Space details |
client.space.getStreamUrl({ mediaKey }) |
Get Space HLS stream URL |
| Method | Description |
|---|---|
client.explore.search({ query, type }) |
Search tweets/users/photos/videos |
| Method | Description |
|---|---|
client.auth.login({ username, password, proxy }) |
Log in and get auth tokens |
| Method | Description |
|---|---|
client.xchat.setup({ authToken, userId, pin }) |
Initialize encrypted DMs |
client.xchat.getConversations({ authToken }) |
List encrypted conversations |
client.xchat.send({ authToken, recipientId, message }) |
Send encrypted message |
client.xchat.getHistory({ authToken, conversationId }) |
Get conversation history |
client.xchat.canDm({ authToken, userIds }) |
Check DM availability |
| Method | Description |
|---|---|
client.dm.sendDm({ authToken, conversationId, text, proxy }) |
Send a DM |
client.dm.getDmPermissions({ authToken, recipientIds }) |
Check DM permissions |
client.dm.getInboxInitialState({ authToken }) |
Get inbox state |
client.dm.getInboxTrusted({ authToken, cursor }) |
Get trusted inbox |
client.dm.getInboxUntrusted({ authToken, cursor }) |
Get message requests |
client.dm.getConversation({ authToken, conversationId }) |
Get conversation messages |
client.dm.getDmUserUpdates({ authToken, cursor }) |
Get DM user updates |
client.dm.acceptConversation({ authToken, conversationId }) |
Accept a conversation |
Use the paginate() and paginatePages() helpers to iterate through all pages automatically:
import TweetAPI, { paginate, paginatePages } from "tweetapi-node";
const client = new TweetAPI({ apiKey: "YOUR_API_KEY" });
// Iterate individual items across all pages
for await (const user of paginate(
(cursor) => client.user.getFollowers({ userId: "123456", cursor }),
)) {
console.log(user.username);
}
// Iterate full pages (access page-level data)
for await (const page of paginatePages(
(cursor) => client.explore.search({ query: "bitcoin", type: "Latest", cursor }),
{ maxPages: 5 }, // optional: limit number of pages
)) {
console.log(`Got ${page.data.length} results`);
console.log(`Next cursor: ${page.pagination.nextCursor}`);
}Works with any paginated endpoint — followers, tweets, search results, list members, community posts, etc.
The SDK automatically retries on transient errors with exponential backoff:
- 429 (Rate Limit) — waits the
retryAfterduration from the API, then retries - 5xx (Server Error) — retries with exponential backoff + jitter
- Network errors — retries on timeouts and connection failures
- 4xx (Client Error) — never retried (400, 401, 403, 404 fail immediately)
Default: 3 retries, 2x backoff, 1s initial delay, 30s max delay.
// Customize retry behavior
const client = new TweetAPI({
apiKey: "YOUR_API_KEY",
retry: {
maxRetries: 5, // default: 3
initialRetryDelay: 2000, // default: 1000ms
backoffMultiplier: 3, // default: 2
maxRetryDelay: 60000, // default: 30000ms
},
});
// Disable retries entirely
const client = new TweetAPI({
apiKey: "YOUR_API_KEY",
retry: false,
});After a 429 response, the SDK exposes the last known rate limit state:
console.log(client.rateLimitInfo);
// { retryAfter: 30, timestamp: 1712345678000 } — or null if no 429 encounteredThe SDK throws typed errors you can catch and handle. With automatic retries enabled (default), you'll only see these after all retry attempts are exhausted:
import TweetAPI, {
TweetAPIError,
AuthenticationError,
RateLimitError,
NotFoundError,
ValidationError,
ServerError,
ConnectionError,
} from "tweetapi-node";
try {
const user = await client.user.getByUsername({ username: "elonmusk" });
} catch (error) {
if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry in ${error.retryAfter}s`);
} else if (error instanceof NotFoundError) {
console.log("User not found");
} else if (error instanceof AuthenticationError) {
console.log("Invalid API key");
} else if (error instanceof ValidationError) {
console.log(`Bad request: ${error.message}`);
} else if (error instanceof ServerError) {
console.log("API is having issues, try again later");
} else if (error instanceof ConnectionError) {
console.log("Network error — check your connection");
} else if (error instanceof TweetAPIError) {
console.log(`Error [${error.code}]: ${error.message}`);
}
}Every error includes:
code— API error code (e.g.,"ACCOUNT_SUSPENDED","RATE_LIMIT")statusCode— HTTP status codemessage— Human-readable error messagedetails— Additional context (field, reason, retryAfter, etc.)
const client = new TweetAPI({
apiKey: "YOUR_API_KEY", // Required
baseUrl: "https://...", // Optional (default: https://api.tweetapi.com)
timeout: 30000, // Optional (default: 30000ms)
retry: { // Optional (default: { maxRetries: 3 })
maxRetries: 3,
initialRetryDelay: 1000,
backoffMultiplier: 2,
maxRetryDelay: 30000,
},
});- Node.js 18+ (uses native
fetch) - TypeScript 5+ (for type definitions)
MIT
TweetAPI is a third-party service and is not affiliated with X Corp.