Skip to content

Articles ​

Read and manage Twitter Articles (long-form posts).

WARNING

Creating, editing, and publishing articles requires an eligible Twitter Premium account. The read methods (get, byUser, published, drafts) work on any account.

The write methods take content_state, which is the article editor's rich-text content state (Draft.js raw content state). emusks forwards it to Twitter unchanged rather than constructing it for you.

articles.get(articleEntityId) ​

Fetch a single article by its entity id. Uses the GraphQL ArticleEntityResultByRestId query.

js
const article = await client.articles.get("1234567890");

articles.forTweet(tweetId) ​

Fetch the full article attached to a post, by the post's id. Uses the GraphQL TweetResultsByRestIds query with the withArticleRichContentState and withArticlePlainText field toggles. Returns null when the post has no article.

js
const article = await client.articles.forTweet("2105653173314887758");
// {
//   rest_id: "2105652739669999616",
//   title: "...",
//   preview_text: "...",
//   plain_text: "...",
//   cover_media: { media_info: { original_img_url, ... } },
//   media_entities: [{ media_id, media_info: { __typename: "ApiImage" | "ApiVideo", ... } }],
//   content_state: { blocks: [...], entityMap: [...] },
//   metadata: { first_published_at_secs },
// }

articles.get(articleEntityId) returns an empty result for other people's articles, so use this method to read them. The id in an x.com/i/article/<id> link is the article entity id, not the post id.

content_state is a Draft.js raw content state. Block types seen so far are unstyled, header-one, header-two, unordered-list-item, ordered-list-item, blockquote and atomic. Inline styles are Bold and Italic. entityMap is an array of { key, value }, and a block's entityRanges[].key points at key. Entity types are LINK (data.url), MEDIA (data.mediaItems[].mediaId, matched against media_entities[].media_id), TWEET (data.tweetId), DIVIDER, TWEMOJI (data.url) and MARKDOWN (data.markdown, used for code blocks). An atomic block holds one entity.

articles.byUser(userId, opts?) ​

Get a user's published articles as a parsed timeline. Uses the GraphQL UserArticlesTweets query.

OptionTypeDescription
userIdstringThe user id
opts.countnumberNumber of results (default 20)
opts.cursorstringPagination cursor
opts.rawbooleanReturn the raw GraphQL response instead of a parsed timeline
js
const timeline = await client.articles.byUser("44196397");

articles.published(userId, opts?) / articles.drafts(userId, opts?) ​

List a user's articles by lifecycle. Both wrap the GraphQL ArticleEntitiesSlice query (slice(userId, lifecycle)).

js
const published = await client.articles.published("44196397");
const drafts = await client.articles.drafts(myUserId);

articles.createDraft(contentState, opts?) ​

Create a new draft article. Uses the GraphQL ArticleEntityDraftCreate mutation.

js
const draft = await client.articles.createDraft(contentState);

articles.updateTitle(articleEntityId, title) ​

Update an article's title. Uses the GraphQL ArticleEntityUpdateTitle mutation.

js
await client.articles.updateTitle(articleEntityId, "My headline");

articles.updateContent(articleEntityId, contentState) ​

Replace an article's body. Uses the GraphQL ArticleEntityUpdateContent mutation.

js
await client.articles.updateContent(articleEntityId, contentState);

articles.updateCoverMedia(articleEntityId, coverMediaId) ​

Set the cover image. Pass a media id from the media upload flow. Uses the GraphQL ArticleEntityUpdateCoverMedia mutation.

js
await client.articles.updateCoverMedia(articleEntityId, mediaId);

articles.publish(articleEntityId) / articles.unpublish(articleEntityId) ​

Publish or unpublish an article. Use the GraphQL ArticleEntityPublish and ArticleEntityUnpublish mutations.

js
await client.articles.publish(articleEntityId);
await client.articles.unpublish(articleEntityId);

articles.remove(articleEntityId) ​

Delete an article. Uses the GraphQL ArticleEntityDelete mutation.

js
await client.articles.remove(articleEntityId);

not affiliated with X Corp.