# X Articles to Markdown Scraper (`maximedupre/x-articles`) Actor

Convert selected public X Articles to clean Markdown and plain text. Submit post IDs or status URLs and get source IDs, titles, authors, media and article links, dates, and public engagement counts when X exposes them. No X credential is needed.

- **URL**: https://apify.com/maximedupre/x-articles.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Developer tools, Automation
- **Stats:** 4 total users, 3 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.55 / 1,000 markdown conversions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 📝 Convert selected X Articles to Markdown

Researchers, writers, and developers can use this Actor to turn selected public X Articles into clean Markdown and plain text. Submit post IDs or status URLs and get each Article's content, source IDs, title, author details, media references, links, dates, and public engagement counts when X exposes them. Use the returned rows for notes, research, citations, or a publishing workflow.

- Save a selected public Article as Markdown with [**Twitter Article to Markdown**](https://apify.com/maximedupre/x-articles/examples/twitter-article-to-markdown).
- Pull one selected source into a structured row with [**X Article Extractor**](https://apify.com/maximedupre/x-articles/examples/x-article-extractor).
- Convert a public X Article for notes with [**Convert X Article to Markdown**](https://apify.com/maximedupre/x-articles/examples/convert-x-article-to-markdown).
- Prepare an X Article for citations with [**X Article to Markdown**](https://apify.com/maximedupre/x-articles/examples/x-article-to-markdown).
- Turn a selected public source into reusable text with [**X Article Converter**](https://apify.com/maximedupre/x-articles/examples/x-article-converter).

#### 📦 Markdown rows for selected X Articles

Each submitted source can produce one dataset row with its public X Article content and source context. The main output is clean Markdown plus plain text, with identifiers and useful public metadata alongside it.

**Content**

- `markdown` keeps the Article body in readable Markdown.
- `plainText` gives the Article body without Markdown formatting.
- `title` and `preview` show the Article name and a short source preview when available.

**Source context**

- `sourceUrl`, `postId`, and `articleId` identify the public source.
- `author` can include the public name, username, profile links, verification, and follower count.
- `publishedAt` and `lastModifiedAt` give Article dates when X exposes them.
- `coverImage` and `inlineImages` contain source image URLs and dimensions when available. The Actor returns references, not downloaded media files.
- `links` keeps link text and resolved outbound destinations from the Article body.
- `engagement` contains public counts captured at extraction time when exposed.
- `extractedAt` records when the Actor read the Article.

#### ▶️ Run with public Article sources

1. Enter one or more public X post IDs or status URLs.
2. You can mix numeric IDs and URLs in the same input.
3. Run the Actor and open the default dataset to review the Article rows.

The Actor reads Articles available to logged-out visitors. It does not search X, find Articles by author or timeline, or turn ordinary posts, threads, reposts, or link cards into Articles. It does not access private, protected, deleted, login-gated, geographic-restricted, subscriber-only, or paywalled content, or bypass CAPTCHA and other access restrictions.

#### ⚙️ Input

Add the public Article sources you want to read. Each value can be a numeric X post ID or a public `x.com` or `twitter.com` status URL.

**Input fields**

| Field | Type | What it does |
|---|---|---|
| `articleSources` | array of strings | Accepts one or more public X post IDs or status URLs. You can mix both forms in one run. |

**Example input**

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

```json
{
  "articleSources": [
    "https://x.com/trq212/status/2052809885763747935"
  ]
}
```

#### 🧾 Output

The output schema exposes `dataset`, a URL that opens the default dataset view. Each dataset row uses the shape below. Optional fields may be absent when X does not expose them.

**Dataset row**

| Field | Type | What it does |
|---|---|---|
| `sourceUrl` | URL | Public X status URL for the Article source. |
| `postId` | string | Stable ID of the public X post that contains the Article. |
| `articleId` | string | Stable ID of the X Article. |
| `title` | string | Title shown for the X Article. |
| `preview` | string, optional | Short preview text provided for the Article source when available. |
| `markdown` | string | Article body converted to readable Markdown. |
| `plainText` | string | Plain-text rendering of the Article body. |
| `author` | object, optional | Public identity and profile details for the Article author when available. |
| `author.name` | string, optional | Public display name of the Article author when available. |
| `author.username` | string, optional | Public X username of the Article author when available. |
| `author.profileUrl` | URL, optional | Public X profile URL for the Article author when available. |
| `author.profileImageUrl` | URL, optional | Source URL of the author's public profile image when available. |
| `author.isVerified` | boolean, optional | Whether X reports the Article author as verified. |
| `author.followersCount` | integer, optional | Public follower count for the Article author. |
| `publishedAt` | date-time string, optional | Time when the Article was published when exposed by X. |
| `lastModifiedAt` | date-time string, optional | Time when the Article was last modified when exposed by X. |
| `coverImage` | object, optional | Source reference for the Article cover image when available. |
| `coverImage.url` | URL | Source URL of the cover image. |
| `coverImage.width` | integer, optional | Cover image width in pixels when available. |
| `coverImage.height` | integer, optional | Cover image height in pixels when available. |
| `inlineImages` | array of objects | Source references for images used inside the Article body. |
| `inlineImages[].url` | URL | Source URL of an inline image. |
| `inlineImages[].width` | integer, optional | Inline image width in pixels when available. |
| `inlineImages[].height` | integer, optional | Inline image height in pixels when available. |
| `links` | array of objects | Links preserved from the Article body. |
| `links[].text` | string | Link text shown in the Article body. |
| `links[].url` | URL | Resolved outbound destination of the link. |
| `engagement` | object, optional | Public engagement counts captured when the Article was extracted when exposed by X. |
| `engagement.replyCount` | integer, optional | Public reply count for the containing X post. |
| `engagement.repostCount` | integer, optional | Public repost count for the containing X post. |
| `engagement.likeCount` | integer, optional | Public like count for the containing X post. |
| `engagement.quoteCount` | integer, optional | Public quote count for the containing X post. |
| `engagement.bookmarkCount` | integer, optional | Public bookmark count for the containing X post. |
| `engagement.viewCount` | integer, optional | Public view count for the containing X post. |
| `extractedAt` | date-time string | Time when the Actor extracted the Article. |

**Example dataset row**

The row below is shortened. Its Markdown and plain-text bodies are shown as `"..."` so the example stays readable. The other values are from a successful current-beta run.

```json
{
  "sourceUrl": "https://x.com/trq212/status/2052809885763747935",
  "postId": "2052809885763747935",
  "articleId": "2052796100608974848",
  "title": "Using Claude Code: The Unreasonable Effectiveness of HTML",
  "markdown": "...",
  "plainText": "...",
  "preview": "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",
  "author": {
    "name": "Thariq is on vacation",
    "username": "trq212",
    "profileUrl": "https://x.com/trq212",
    "profileImageUrl": "https://pbs.twimg.com/profile_images/1976939058741039104/r3GgzqRh_200x200.jpg",
    "isVerified": true,
    "followersCount": 340718
  },
  "publishedAt": "2026-05-08T17:56:30.000Z",
  "lastModifiedAt": "2026-05-19T21:04:23.000Z",
  "coverImage": {
    "url": "https://pbs.twimg.com/media/HHz_ftzaIAAwkQs.jpg",
    "width": 2400,
    "height": 960
  },
  "inlineImages": [
    {
      "url": "https://pbs.twimg.com/media/HH0Bp86bUAAJDyZ.jpg",
      "width": 1640,
      "height": 880
    },
    {
      "url": "https://pbs.twimg.com/media/HH0Ao0tbYAAOF9e.jpg",
      "width": 1520,
      "height": 800
    },
    {
      "url": "https://pbs.twimg.com/media/HH0BFWLbMAEk_7T.jpg",
      "width": 1440,
      "height": 900
    },
    {
      "url": "https://pbs.twimg.com/media/HH0BRSQbMAAuuof.png",
      "width": 1440,
      "height": 900
    },
    {
      "url": "https://pbs.twimg.com/media/HH0BXqjboAAHGsw.jpg",
      "width": 1440,
      "height": 900
    },
    {
      "url": "https://pbs.twimg.com/media/HH0AgqJbcAAaEcZ.jpg",
      "width": 1640,
      "height": 840
    },
    {
      "url": "https://pbs.twimg.com/media/HHz_q48aAAAaCfW.jpg",
      "width": 1440,
      "height": 840
    },
    {
      "url": "https://pbs.twimg.com/media/HH0CDc6a8AAy1bv.png",
      "width": 684,
      "height": 340
    },
    {
      "url": "https://pbs.twimg.com/media/HH0FbKebUAAsRPr.jpg",
      "width": 1600,
      "height": 880
    }
  ],
  "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/"
    }
  ],
  "engagement": {
    "replyCount": 1098,
    "repostCount": 2291,
    "likeCount": 17806,
    "quoteCount": 1937,
    "bookmarkCount": 34489,
    "viewCount": 14611690
  },
  "extractedAt": "2026-09-03T20:37:04.364Z"
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. The primary event is `Markdown conversion`: you are charged once when a selected public Article converts to Markdown successfully. The current rate depends on your Apify tier and appears on the Store page.

#### 🔌 Integrations

Read the dataset in Apify Console or through its API, then use the returned rows in your own workflow. Article and media links stay as source references.

Watch the setup video:

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### Can I mix post IDs and status URLs?

Yes. Add numeric public X post IDs, public `x.com` status URLs, public `twitter.com` status URLs, or a mix of these values in `articleSources`.

##### What if a source is an ordinary post or a private Article?

The Actor only reads public long-form Articles that are available to logged-out visitors. It does not convert ordinary posts or access private, deleted, protected, login-gated, geographic-restricted, subscriber-only, or paywalled content.

##### Does the Actor download Article images?

No. It returns source image URLs and dimensions when available. It does not download or permanently host the media files.

##### Are author, date, and engagement fields always present?

No. These are optional fields in the dataset and appear when X exposes the data.

##### Can it find top X Articles?

No. You submit the sources you want to read. The Actor does not search X or discover Articles by keyword, profile, or timeline.

##### Can I use X Articles on mobile?

Yes, if you can copy a public post ID or status URL from your mobile browser or the X app. This Actor reads the source you provide; it does not write or publish an Article.

##### Does it show how to write an article on X mobile or in the X app?

No. It extracts existing public Articles. It is not a writing or publishing tool.

##### Where can I see X Articles examples?

The five task examples above show common ways to send a selected source and get an Article row.

### 📝 Changelog

**v0.0** (03-09-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~x-articles/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Twitter Scraper](https://apify.com/maximedupre/twitter-scraper) finds public X posts and profiles when you need to locate a source before submitting it here.
- [Webpage Text Extractor](https://apify.com/maximedupre/webpage-text-extractor) extracts clean text or Markdown from public webpages outside X.
- [X(Twitter) Article to Markdown](https://apify.com/fastcrawler/x-twitter-article-to-markdown) converts selected X Articles to Markdown with a direct X-focused alternative.
- [X/Twitter Article Markdown API](https://apify.com/parsebird/x-twitter-article-markdown) batches X Article IDs and exports Markdown in common file formats.
- [X (Twitter) Article to Markdown Scraper - Long Form Posts](https://apify.com/seemuapps/x-article-to-markdown-scraper) converts long-form X Articles to Markdown for AI or RAG workflows.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `articleSources` (type: `array`):

Enter one or more public X post IDs or status URLs. You can mix both, for example `1234567890123456789` or `https://x.com/user/status/1234567890123456789`.

## Actor input object example

```json
{
  "articleSources": [
    "https://x.com/trq212/status/2052809885763747935"
  ]
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "articleSources": [
        "https://x.com/trq212/status/2052809885763747935"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/x-articles").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "articleSources": ["https://x.com/trq212/status/2052809885763747935"] }

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/x-articles").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "articleSources": [
    "https://x.com/trq212/status/2052809885763747935"
  ]
}' |
apify call maximedupre/x-articles --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/x-articles"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/u9okMlLtcUphiZtpl/builds/DdZYbqtT1xpoV1RUo/openapi.json
