Skip to content

Requests

Beyond the top-posts helpers, emusks gives you a low-level request primitive and thin fetch-and-decode wrappers so you can hit any Jetfuel route directly.

client.jf(route, opts?)

The low-level primitive, alongside client.graphql, client.v1_1 and client.v2. It hits https://x.com/i/jfapi/<route> with the same auth, fingerprint and proxy plumbing as the rest of the library, adds the Jetfuel-specific headers (x-jf-client-theme, x-jf-v), and returns the raw binary response.

OptionTypeDescription
routestringPath under /i/jfapi (may include a query string).
opts.paramsobjectQuery params (merged into the URL).
opts.methodstringHTTP method (default "GET"; use "POST" for actions/ routes).
opts.bodystringRequest body for POST actions.
opts.themestringx-jf-client-theme value (default "business").
opts.jfVersionstringx-jf-v value (default "JP-5").
opts.headersobjectExtra headers (merged last).
opts.refererstringOverride the Referer (defaults to the matching i/jf mount).

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?)

Fetch a route and decode its binary payload into JSON in one call. Same options as client.jf. Returns the decoded wire format 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?)

Alias for page, named to read better when fetching 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?)

Fetch a route and return the raw response (the client.jf result) without decoding. Use this when you want the bytes, the headers, or to decode later.

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

Image helpers

Jetfuel also server-renders images for any public tweet. These helpers return the URLs (no auth needed to fetch them).

jetfuel.ogImageUrl(tweetId)

The Open Graph share card (1200x630 PNG): avatar, name, verified/affiliate badge, tweet text, media and the X logo. Always light theme. Private or deleted tweets return 404.

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

jetfuel.mediaPreviewUrl(tweetId)

A PNG re-render of a tweet's attached media (1200x935). Returns 404 for tweets with no media.

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

Other routes

The Jetfuel surface is large (the Creator hub, Stories, the sports and live-events hub, onboarding). Most routes are pure UI rather than data feeds, 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. A bare GET returns a 400 or a validation message:

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

not affiliated with X Corp.