Convert a Batch of X Posts to Markdown in One Run
A list of status URLs in, Markdown rows out — for reading lists, research archives, and content pipelines.

A reading list is a URL list — convert it all at once. Thirdwatch's Tweet to Markdown converts public X posts — including long-form articles — to clean Markdown with author and engagement metadata, through a guest path that needs no login.
Skip the setup: Run this as a ready-to-go task on Apify — pre-loaded with the configuration from this guide.
Why convert posts in bulk
Collecting posts for a digest or research folder means converting each one — the per-post path doesn't survive past a handful of URLs.
urls takes the whole list; every post becomes its own row, ordered as supplied.
The converter resolves each status URL through X's guest API and renders the body as Markdown, so the archive path is a URL list in and Markdown rows out.
How does this compare to the alternatives?
| Approach | Cost model | Output | Effort |
|---|---|---|---|
| Copy-paste into a doc | Free | Unformatted text | One post at a time |
| X API v2 | Paid tiers, auth | JSON you must convert yourself | App approval + keys |
| Thirdwatch Tweet to Markdown | Pay per post | Clean Markdown + engagement | Paste a URL, run |
Why this Actor
- Long-form support — note tweets and X articles, not just 280-character posts.
- Clean Markdown output: links, headings, and media references preserved.
- No login or cookies — the guest path is used.
- Engagement counts (replies, reposts, likes) land on every row.
- Batch input converts a reading list in one run.
How to do it in 3 steps
Step 1: Configure the input
Set the inputs as shown below — urls takes the targets, each entry is an x.com or twitter.com status URL.
Step 2: Run the Actor
Run it from the console, the API, or the linked saved task. One dataset row is written per post.
Step 3: Use the output
Each row carries the post body as markdown, the author handle and display name, timestamp, engagement counts, and an isArticle flag for long-form posts.
{
"urls": [
"https://x.com/jack/status/20",
"https://x.com/elonmusk/status/1519480761749016577"
]
}Each dataset row looks like:
{
"id": "20",
"url": "https://x.com/jack/status/20",
"author": "jack",
"authorName": "jack",
"createdAt": "2006-03-21T20:50:14.000Z",
"isArticle": false,
"markdown": "just setting up my twttr",
"replyCount": 12000,
"retweetCount": 95000,
"favoriteCount": 180000
}What to watch for
Public posts only — protected accounts and deleted tweets return error rows. The guest path occasionally rate-limits; retry error rows rather than treating them as permanent failures.
Related use cases
- Convert an X Post to Clean Markdown
- Export an X Long-Form Article as Markdown
- Feed X Posts to an LLM as Clean Markdown
- Snapshot a Post's Engagement Alongside Its Markdown
- All Thirdwatch use-case guides
Run the Tweet to Markdown on Apify Store — pay per result, free to try, no credit card to test.
Frequently asked questions
Does it handle long-form X articles?
Yes — long-form posts and note tweets convert fully, and `isArticle` flags them on the row.
Do I need an X account or API key?
No — the Actor uses the public guest path, so there is no auth to manage.
What about protected or deleted posts?
They return `error` rows — public posts only.
Are links and media preserved?
Links become Markdown links and media attachments are referenced in the body; the row is meant for text-first pipelines.
Why did a post fail once but work on retry?
The guest path is occasionally rate-limited; transient failures come back as `error` rows worth a retry.
Can I convert a whole thread?
Pass each status URL in the thread — each becomes its own Markdown row, ordered by your input list.