Skip to content

Configuration

emusks lets you customize how it connects to Twitter/X. You can choose which client to emulate, which GraphQL endpoint to target, route traffic through a proxy, and access the raw API layers directly.

Client selection

Twitter/X uses different API configurations depending on which app you're using. emusks can emulate any of the official clients, each with its own bearer tokens and HTTP fingerprints.

js
import Emusks from "emusks";

const client = new Emusks();
await client.login({
  auth_token: "your_auth_token_here",
  client: "tweetdeck", // emulate the tweetdeck client (premium-only)
});

Please note that the availability of clients constantly changes, and some may get your account suspended.

Changing the client usually doesn't require getting a new auth token, but you may need to change it if you sign out or get CAPTCHA'd.

The current built-in clients are android, iphone, ipad, mac, old, web, tweetdeck, along with a few leaked ones: advertisers, ads_manager_next, advertiser_interface, corporate_cms, ads_broken, audience_manager_internal, and tweets_manager.

Custom clients

By default, emusks uses the "web" client, which is the most common and least likely to raise suspicion. However, if you want to emulate a different client or use a custom bearer token, you can do so with the client option.

To use a custom client, pass an object instead of a string:

js
{
  bearer: "AAAAAAAAAAAAAAAAAAAAA…",
  fingerprints: {
    "user-agent":
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
    ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,35-5-27-16-0-10-13-23-45-65037-17613-18-65281-51-43-11,4588-29-23-24,0",
    ja4r: "t13d1516h2_002f,0035,009c,009d,1301,1302,1303,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0012,0017,001b,0023,002b,002d,0033,44cd,fe0d,ff01_0403,0804,0401,0503,0805,0501,0806,0601",
  },
},

GraphQL endpoint

Twitter/X exposes the same GraphQL API on multiple endpoints. emusks lets you pick which one to use:

NameBase URLDefault transaction IDs
webhttps://x.com/i/api/graphql/<queryId>/<queryName>on
mainhttps://api.x.com/graphql/<queryId>/<queryName>off
tweetdeckhttps://pro.x.com/i/api/graphql/<queryId>/<queryName>off
web_twitterhttps://twitter.com/i/api/graphql/<queryId>/<queryName>on
main_twitterhttps://api.twitter.com/graphql/<queryId>/<queryName>off
tweetdeck_twitterhttps://pro.twitter.com/i/api/graphql/<queryId>/<queryName>off

The default endpoint is web. Set it with the endpoint option at login:

js
const client = new Emusks();
await client.login({
  auth_token: "your_auth_token_here",
  endpoint: "main", // "web" | "main" | "tweetdeck" | "web_twitter" | "main_twitter" | "tweetdeck_twitter"
});

You can also change it after login by setting the property directly:

js
client.graphqlEndpoint = "tweetdeck";

Transaction IDs

The web endpoint expects an x-client-transaction-id header on every GraphQL request. emusks generates these automatically using the x-client-transaction-id package.

The main and tweetdeck endpoints don't require transaction IDs, so they are off by default for those endpoints. You can override this with the transactionIds option:

js
const client = new Emusks();
await client.login({
  auth_token: "your_auth_token_here",
  endpoint: "main",
  transactionIds: true, // force transaction IDs on for any endpoint
});

Or toggle it after login:

js
client.transactionIds = false; // disable even on web

When to change endpoints

Different endpoints can behave differently under rate-limiting. If you're hitting limits on web, switching to main may help — and vice versa. The tweetdeck endpoint mirrors the TweetDeck (X Pro) web app.

Proxy support

Route all API traffic through an HTTP proxy. This is useful for avoiding rate limits, changing IP addresses, or accessing Twitter from restricted networks.

js
const client = new Emusks();
await client.login({
  auth_token: "your_auth_token_here",
  proxy: "protocol://user:pass@host:port", // (supports http, socks4, socks5, socks5h)
});

Rotating proxies are not supported by default and I don't recommend using them. While you could constantly rotate the proxy sent to the client yourself, Twitter will most likely notice it and get suspicious of a single session being used from many IPs.

Handling errors

emusks throws errors sent from the Twitter GraphQL API by default. You can catch these errors using a try-catch block, and for long-running apps we recommnd setting a system for you to be notified in case your account gets locked or rate-limited:

83 |       method,
84 |     )
85 |   ).json();
86 |
87 |   if (res?.errors?.[0]) {
88 |     throw new Error(res.errors.map((err) => err.message).join(", "));
                   ^
error: Authorization: Denied by access control: Missing TwitterUserNotSuspended; To protect our users from spam and other malicious activity, this account is temporarily locked. Please log in to https://twitter.com to unlock your account.

Next steps

You're all set! Explore the helper namespaces to start building:

  • Tweets — Create, like, retweet, and manage tweets
  • Users — Follow, block, mute, and look up users
  • Search — Search tweets, users, and media
  • Account — Manage your account settings and security

not affiliated with X Corp.