Twitter Article Scraper avatar

Twitter Article Scraper

Pricing

$0.10 / 1,000 x articles

Go to Apify Store
Twitter Article Scraper

Twitter Article Scraper

Extract public long-form X Articles from post URLs or numeric post IDs. Get Markdown, plain text, author details, dates, links, media references, content blocks, and public engagement counts in a structured dataset.

Pricing

$0.10 / 1,000 x articles

Rating

0.0

(0)

Developer

Maxime Dupré

Maxime Dupré

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

📰 Turn selected X Articles into usable text

Researchers, journalists, and AI teams can submit public X post URLs or numeric post IDs and get the public Article body as Markdown and plain text. Each dataset row keeps the source post, author, publication dates, links, media references, content blocks, and public engagement counts when X exposes them, so you can cite, search, archive, or analyze the text.

📄 See the Article, source post, and author

A dataset row groups three top-level objects: article, sourcePost, and author. Optional source fields can be absent when X does not expose them.

Returned data

The article object holds the Article body, structure, media, and links. sourcePost keeps the containing post and its public engagement snapshot. author keeps the public profile fields that X exposes.

▶️ Run the X Article scraper

  1. Choose Public post URLs or Numeric post IDs in Find Articles by.
  2. Add the matching public sources. The other source section is not used for that run.
  3. Start the run and open the default dataset to review the nested Article rows.

What the Actor reads

The Actor reads selected public long-form Articles that are accessible without an X login. It does not search X or discover Articles from a profile, timeline, keyword, or feed. It does not scrape ordinary posts, threads, replies, quote posts, or profiles.

Access limits

Private, deleted, paywalled, geo-restricted, login-gated, and CAPTCHA-protected content is outside the supported scope. Media is returned as source references; the Actor does not download or permanently store media files.

⚙️ Input

Choose one discovery method, then add sources in the matching section. The other section is not used for that run.

Input fields

FieldTypeWhat it does
discoveryMethodchoiceRequired. Choose postUrls to use public post URLs or postIds to use numeric post IDs.
postUrlsarray of objectsWhen discoveryMethod is postUrls, add one or more full X or Twitter status URLs for posts that contain public long-form Articles.
postUrls[].urlstringFull public X or Twitter post URL with a numeric status ID.
postIdsarray of stringsWhen discoveryMethod is postIds, add one or more numeric IDs for public X posts that contain long-form Articles.

Example input

This example is copied from the public input of a successful current-beta run:

{
"discoveryMethod": "postUrls",
"postUrls": [
{
"url": "https://x.com/tonysimons_/status/2060527240098587085"
}
]
}

🧾 Output

The output schema provides a link to the default Apify dataset. Each saved row follows the nested shape documented below.

Run output

FieldTypeWhat it does
datasetURLOpens the default dataset for the run.

Dataset row

FieldTypeWhat it does
articleobjectGroups the public Article, its content, media, and links.
article.idstringStable Article ID assigned by X.
article.urlstringCanonical public URL for the Article.
article.titlestringArticle title when the source provides one.
article.previewTextstringSource-provided Article preview when available.
article.publicationobjectSource dates for the Article.
article.publication.createdAtdate-time stringTime when the source says the Article was created.
article.publication.firstPublishedAtdate-time stringTime when the source says the Article was first published.
article.publication.lastModifiedAtdate-time stringTime when the source says the Article was last modified.
article.contentobjectHolds readable and structured Article content.
article.content.markdownstringComplete publicly available Article body rendered as Markdown.
article.content.plainTextstringArticle body rendered as plain text.
article.content.blocksarray of objectsSource content blocks when available.
article.content.blocks[].typestringSource-reported type of a content block.
article.content.blocks[].textstringText carried by a block when available.
article.content.blocks[].levelintegerSource-reported heading or nesting level when available.
article.content.blocks[].itemsarray of stringsText items in a list-like block when available.
article.content.blocks[].inlinearray of objectsInline text runs and formatting in a block when available.
article.content.blocks[].inline[].textstringText in an inline run.
article.content.blocks[].inline[].formatsarray of stringsSource formatting marks on an inline run.
article.content.blocks[].inline[].urlstringLink destination for an inline run when available.
article.content.referencesarray of objectsSource references used by structured Article content.
article.content.references[].idstringSource ID for a content reference when available.
article.content.references[].typestringSource-reported reference type.
article.content.references[].urlstringDestination URL for a content reference when available.
article.mediaobjectSource references for cover and inline media.
article.media.coverobjectCover media reference when available.
article.media.cover.idstringSource media ID when available.
article.media.cover.urlstringURL where the cover media is available.
article.media.cover.typestringSource-reported cover media type when available.
article.media.cover.widthintegerCover media width in pixels when available.
article.media.cover.heightintegerCover media height in pixels when available.
article.media.inlinearray of objectsSource references for media inside the Article body.
article.media.inline[].idstringSource media ID when available.
article.media.inline[].urlstringURL where the inline media is available.
article.media.inline[].typestringSource-reported inline media type when available.
article.media.inline[].widthintegerInline media width in pixels when available.
article.media.inline[].heightintegerInline media height in pixels when available.
article.linksarray of objectsLinks embedded in the Article.
article.links[].textstringText shown for a link in the Article.
article.links[].urlstringResolved destination of the link.
sourcePostobjectThe public X post that contains the Article.
sourcePost.idstringStable ID of the containing post.
sourcePost.urlstringCanonical public URL of the containing post.
sourcePost.engagementobjectPublic engagement counts for the containing post when available.
sourcePost.engagement.likesintegerReported like count.
sourcePost.engagement.repliesintegerReported reply count.
sourcePost.engagement.repostsintegerReported repost count.
sourcePost.engagement.quotesintegerReported quote-post count.
sourcePost.engagement.bookmarksintegerReported bookmark count.
sourcePost.engagement.viewsintegerReported view count.
authorobjectPublic profile shown for the Article author.
author.idstringAuthor ID assigned by X when available.
author.namestringPublic author display name when available.
author.usernamestringPublic author username.
author.profileUrlstringPublic author profile URL when available.
author.isVerifiedbooleanWhether X marks the author as verified.
author.descriptionstringPublic profile description when available.
author.locationstringPublic profile location when available.
author.websiteUrlstringWebsite shown on the public profile when available.
author.profileImageUrlstringPublic profile image URL when available.

Genuine current-beta row

The row below is shortened. The markdown, plainText, blocks, references, and inline media values use "..." as omission markers. The remaining values are from a successful current-beta run.

{
"article": {
"id": "2052796100608974848",
"url": "https://x.com/trq212/status/2052809885763747935",
"title": "Using Claude Code: The Unreasonable Effectiveness of HTML",
"previewText": "This is now also on the Claude Blog.\n\nMarkdown has become the dominant file format used by agents to communicate with us. It’s simple, portable, has some rich text capability and is easy for you to",
"publication": {
"createdAt": "2026-05-08T17:56:30.000Z",
"firstPublishedAt": "2026-05-08T17:56:30.000Z",
"lastModifiedAt": "2026-05-19T21:04:23.000Z"
},
"content": {
"markdown": "...",
"plainText": "...",
"blocks": "...",
"references": "..."
},
"media": {
"cover": {
"id": "2052796450510348288",
"url": "https://pbs.twimg.com/media/HHz_ftzaIAAwkQs.jpg",
"type": "ApiImage",
"width": 2400,
"height": 960
},
"inline": "..."
},
"links": [
{
"text": "Claude Blog",
"url": "https://claude.com/blog/using-claude-code-the-unreasonable-effectiveness-of-html"
},
{
"text": "https://thariqs.github.io/html-effectiveness",
"url": "https://thariqs.github.io/html-effectiveness/"
},
{
"text": "https://x.com/trq212/status/2017024445244924382",
"url": "https://x.com/trq212/status/2017024445244924382"
},
{
"text": "https://thariqs.github.io/html-effectiveness/",
"url": "https://thariqs.github.io/html-effectiveness/"
}
]
},
"sourcePost": {
"id": "2052809885763747935",
"url": "https://x.com/trq212/status/2052809885763747935",
"engagement": {
"likes": 17841,
"replies": 1098,
"reposts": 2292,
"quotes": 1938,
"bookmarks": 34604,
"views": 14717658
}
},
"author": {
"username": "trq212",
"id": "352806502",
"name": "Thariq",
"profileUrl": "https://x.com/trq212",
"isVerified": true,
"description": "Claude Code @anthropicai. prev YC W20, @spc, @medialab",
"location": "SF via Toronto",
"websiteUrl": "http://thariq.io",
"profileImageUrl": "https://pbs.twimg.com/profile_images/1976939058741039104/r3GgzqRh_200x200.jpg"
}
}

💳 Pricing

This Actor uses pay-per-event pricing. The X Article event is charged only when one public long-form Article is extracted and saved. Check the Actor page for the current event price.

🔌 Integrations

Results are available in the default Apify dataset and through the Apify API. Use the dataset export tools or the dataset API URL to pass Article rows to your own research, archive, or text workflow.

For a short walkthrough of using an Actor in an Apify workflow, see:

❓ FAQ

Can I submit URLs and numeric IDs in one run?

No. Choose one discovery method and fill in its matching section for each run.

What if a post is an ordinary tweet or its Article is not public?

The Actor is for public long-form X Articles only. The source must be readable without an X login, and ordinary posts and restricted content are outside the supported scope.

Do I need an X login, developer API key, or cookies?

No. You do not need to give the Actor an X login, developer API key, or cookies.

Does the Actor find Articles from a profile or keyword?

No. Submit the public post URL or numeric post ID for each Article you want to read. The Actor does not perform profile discovery or X search.

Which post URL should I submit when an Article was reposted?

Use the public post that contains the Article. An unrelated repost is not a reliable Article source.

What are content blocks and references for?

They preserve source-provided structure and reference details for workflows that need more than the Markdown or plain-text rendering.

Are engagement counts historical?

No. They are public counts captured with the Article and can change after extraction. Optional counts may be absent when X does not expose them.

Does the Actor download Article images?

No. It returns source media references, including available URLs and dimensions, but it does not create permanent media copies.

Can it read private, subscriber-only, or paywalled Articles?

No. The Actor does not bypass login, payment, geographic, deletion, or other access restrictions.

📝 Changelog

v0.0 (18-09-2026)

  • Initial release.

🆘 Support

For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡

Made with ❤️ by Maxime Dupré