Twitter Internal API Client
twitter-openapi-typescript is a TypeScript library that provides an implementation of Twitter's (now X's) *internal* API, allowing programmatic interaction with the platform without relying on the official, public API. It is currently in a pre-1.0 development phase, indicated by its `0.0.55` version, suggesting frequent updates and potential breaking changes without prior notice due to the nature of interacting with internal, undocumented endpoints. The library emphasizes ease of use with guest clients for public data access and supports authenticated clients via cookie-based login (`ct0`, `auth_token`). A key differentiator is its focus on the internal API, which offers capabilities beyond the public API, though at a higher risk of instability and account suspension. The project ships with full TypeScript types, enhancing developer experience.
Common errors
-
API request failed with status 401 Unauthorized
cause Invalid, expired, or improperly configured authentication cookies/tokens.fixEnsure `ct0` and `auth_token` are current and correctly passed to `getClientFromCookies()`. Check if the token's OS platform matches the client's `sec-ch-ua-platform` header. -
API request failed with status 429 Too Many Requests
cause Twitter's internal API rate limits have been exceeded.fixImplement exponential backoff or introduce delays between requests. Consider using authenticated clients which might have higher rate limits than guest clients. -
User not found (or similar data parsing errors)
cause The requested user does not exist, or Twitter's API response structure for user data has changed unexpectedly.fixVerify the `screenName` is correct. Check GitHub issues or the library's test cases for recent changes to API responses. Add robust error handling and null checks for API data.
Warnings
- breaking This library relies on Twitter's undocumented internal APIs, which are subject to frequent and unannounced changes. This can lead to sudden breaking changes in the library's functionality, requiring updates or manual workarounds.
- breaking Modifying internal static variables (e.g., `TwitterOpenApi.fetchApi`, `TwitterOpenApi.twitter`, `TwitterOpenApi.bearer`) beyond what is explicitly documented can lead to account suspension by Twitter.
- gotcha Authentication tokens are often bound to the operating system (specifically, the `sec-ch-ua-platform` header) that issued them. Using a token generated on Windows with a default Linux-configured client (or vice-versa) will result in authentication failures.
- gotcha The library is pre-1.0 (version 0.0.55), indicating that its API is not yet stable. Expect frequent updates, potential changes to method signatures, and evolving data structures without strict semantic versioning adherence.
- gotcha The project is dual-licensed under a Custom License and GNU Affero General Public License v3.0 (AGPLv3). AGPLv3 is a strong copyleft license that requires distributing the source code of your application if it interacts with the AGPLv3-licensed library over a network.
Install
-
npm install twitter-openapi-typescript -
yarn add twitter-openapi-typescript -
pnpm add twitter-openapi-typescript
Imports
- TwitterOpenApi
const TwitterOpenApi = require('twitter-openapi-typescript').TwitterOpenApi;import { TwitterOpenApi } from 'twitter-openapi-typescript'; - TwitterOpenApiClient
const { TwitterOpenApiClient } = require('twitter-openapi-typescript');import { TwitterOpenApiClient } from 'twitter-openapi-typescript'; - TwitterOpenApi
import TwitterOpenApi from 'twitter-openapi-typescript';
import { TwitterOpenApi } from 'twitter-openapi-typescript';
Quickstart
import { TwitterOpenApi } from 'twitter-openapi-typescript';
async function getUserDetails() {
const api = new TwitterOpenApi();
// To avoid rate limits or access private data, you might need to log in:
// const client = await api.getClientFromCookies({
// ct0: process.env.TWITTER_CT0 ?? '',
// auth_token: process.env.TWITTER_AUTH_TOKEN ?? ''
// });
const client = await api.getGuestClient();
const response = await client.getUserApi().getUserByScreenName({ screenName: 'elonmusk' });
const userLegacy = response.data?.user?.legacy;
if (userLegacy) {
console.log(`@${userLegacy.screenName}`);
console.log(`Friends Count: ${userLegacy.friendsCount}, Followers Count: ${userLegacy.followersCount}`);
} else {
console.log('User not found or API response format changed.');
}
}
getUserDetails();