Skip to content

Requests ​

These call any Jetfuel route directly, either raw or decoded.

client.jf(route, opts?) ​

The raw Jetfuel request, next to client.graphql, client.v1_1 and client.v2. It calls https://x.com/i/jfapi/<route> with the client's session, fingerprint and proxy, adds the Jetfuel headers x-jf-client-theme and x-jf-v, and returns the binary response. It needs a logged-in client. route is a path under /i/jfapi and can include a query string.

OptionTypeDescription
paramsobjectQuery parameters added to the URL
methodstringDefault "GET". actions/ routes need "POST".
bodystringRequest body for POST actions
themestringx-jf-client-theme. Default "business".
jfVersionstringx-jf-v. Default "JP-5".
headersobjectExtra headers, applied last
refererstringReferer. Default is the matching x.com/i/jf/<route> page.
originstring"jfapi" (default) or "jf" to call https://jf.x.com/<route> instead

It resolves to:

js
{
  status,       // HTTP status
  headers,      // response headers
  contentType,  // e.g. "text/plain"
  buffer,       // Node Buffer of the raw bytes
  text(),       // bytes as a UTF-8 string
  decode(),     // bytes decoded into the structured wire-format tree
}
js
const res = await client.jf("creators/inspiration/remote/urt", {
  params: { engagement: "Likes", period: "Daily", country: "USA" },
});
res.status;       // 200
res.buffer.length // 173
res.decode();     // { frame, strings, nodes, atoms, lists, timelineTokens }

jetfuel.page(route, opts?) ​

Fetches a route and decodes it in one call. Takes the same options as client.jf and returns the decoded payload plus status and contentType.

js
const studio = await client.jetfuel.page("creators/studio");
studio.frame;   // { payloadLen, count, footer }
studio.strings; // every string in the page
studio.nodes;   // [{ type, key }, ...]

jetfuel.remote(route, opts?) ​

The same as page, named for remote/ data feeds.

js
const feed = await client.jetfuel.remote("creators/inspiration/remote/urt", {
  params: { engagement: "Bookmarks", period: "Weekly" },
});
feed.timelineTokens; // ["VGltZWxpbmU6..."]

jetfuel.raw(route, opts?) ​

Fetches a route and returns the client.jf result without decoding it, for when you want the bytes or the headers.

js
const res = await client.jetfuel.raw("creators/inspiration/top_posts");
res.buffer;          // raw bytes
res.decode();        // decode on demand

Image helpers ​

Jetfuel renders images of public tweets on the server. These helpers only build the URLs, and fetching them needs no login.

jetfuel.ogImageUrl(tweetId) ​

The Open Graph share card, a 1200x630 PNG with the avatar, name, badges, tweet text, media and the Twitter logo, always in the light theme. Private or deleted tweets return 404.

js
client.jetfuel.ogImageUrl("1895256113429241856");
// "https://jf.x.com/images/post/1895256113429241856"

jetfuel.mediaPreviewUrl(tweetId) ​

A 1200x935 PNG of a tweet's attached media. Tweets without media return 404.

js
client.jetfuel.mediaPreviewUrl("1895256113429241856");
// "https://jf.x.com/images/media-preview/1895256113429241856"

Other routes ​

Most Jetfuel routes describe UI rather than data, but you can fetch and inspect any of them:

js
await client.jetfuel.page("stories/home");
await client.jetfuel.page("creators/studio");
await client.jetfuel.page("nba/home");

actions/ routes are POST mutations, and a GET returns a 400 or a validation message:

js
await client.jf("onboarding/actions/resendcode", { method: "POST", body: "..." });

not affiliated with X Corp.