Archive X threads as Markdown
EN PT ID

tweet.md API for LLMs 2026: 5 Markdown Workflows

July 14, 2026 · 9 min read · Guide

If you have been treating tweet.md as a URL rewrite trick — the browser trick where you swap x.com with tweet.md and the post renders as clean Markdown — you have been missing the better half. tweet.md also ships a small, well-documented HTTP API that takes the same X posts, threads, and profiles and returns them as plain Markdown your LLM can ingest directly. No JSON, no parsing, no cleanup pass.

The free tier covers casual testing (5 single-post requests per IP per calendar month, thread=off only). Anything more — ancestor chains, branch context, profile dumps, X Articles — requires a paid API key. This guide walks through the API surface, the four authentication methods, the five LLM workflows that pay for themselves in an afternoon, and when to reach for ThreadGrab instead.

Quick take: tweet.md's API returns text/markdown, not JSON. Free tier is single-post only. Paid tier is $5 for 500 credits. Five workflows actually pay off: RAG ingestion, citation pulling, agent tool-use, Obsidian vault sync, and Apple Shortcuts on iOS.

H2-1: What tweet.md's API Actually Returns

The API is single-purpose: given an X post URL (or a handle + post ID, or a profile handle), return a Markdown document with the post text, author handle, timestamp, media links, engagement stats, and any quoted tweets or embedded replies rendered as nested Markdown blocks. The output is text/markdown, never JSON. tweet.md explicitly rejects format=json.

There are three entry points:

All four endpoints take the same query parameters: format, thread, userinfo, stats, metadata, and (for profiles) pinnedpost, latest, replies, articles. The defaults differ slightly between free and paid: the free tier forces thread=off and userinfo=off; the paid tier defaults to thread=ancestors-20 and userinfo=author when those params are omitted.

H2-2: Authentication — Four Methods, One Key

tweet.md accepts the same API key in four different ways. Pick the one that fits your runtime.

MethodHeader / ParamWhen to use
BearerAuthorization: Bearer ***Scripts, agents, and servers (recommended)
iOS keyx-ios-apikey: twmd_key_...Apple Shortcuts — returns text/html with line breaks as <br>
URL param?apikey=twmd_key_...Quick manual tests (avoid sharing URLs that contain it)
Session cookieautomatic after checkout/loginBrowser rewrites in the same browser after topup
Trusted IPwhitelisted in dashboardPublic server IPs — fixed-budget agents without sending a key

The key looks like twmd_key_… and is delivered by email after Stripe checkout, or generated from the dashboard. Trusted IPs let you skip the header entirely for fixed server IPs — useful when you run a cron job on a VPS with a stable address. The precedence rule: if a request includes both a Bearer header and a Trusted IP, the Bearer key wins.

A free tier exists for casual testing but is not what production agents want. The free tier forces thread=off and userinfo=off, which means you get the single post only, no author metadata, no reply context. Five requests per IP per calendar month. Anything beyond smoke-testing needs a paid key.

H2-3: The /i/api/convert Endpoint (Programmatic)

This is the endpoint your agent will call most often. The contract is simple: pass the full x.com URL as a query parameter, get back a Markdown document. Header carries the bearer key.

curl -H "Authorization: Bearer twmd_key_..." \
  "https://tweet.md/i/api/convert?url=https%3A%2F%2Fx.com%2Fjack%2Fstatus%2F20&thread=branch-8"

The response is the full thread rendered as Markdown. The thread=branch-8 parameter caps the response at 8 posts total: ancestors first (the chain above your post), then replies below. The actual response headers carry the metadata your agent should bill against:

These headers are appended to the HTTP response only, never to the Markdown body. Your agent can read them to log credit usage without polluting the content the LLM ingests.

H2-4: The /i/api/profile Endpoint (Profile Scraping)

Profiles are billed differently. The base profile costs 2 credits, plus 1 credit per post returned in any enabled section (pinned, latest, replies, articles). The free tier does not include profile access at all.

curl -H "Authorization: Bearer twmd_key_..." \
  "https://tweet.md/i/api/profile?handle=jack&latest=10&replies=5"

Defaults are conservative: pinned post on, latest 5 posts, replies off, articles off. The latest, replies, and articles parameters each accept a range (latest 5-50, replies and articles 5-20). Each post returned is +1 credit. For a profile dump with the pinned post, 10 latest, and 5 replies, you are looking at 2 + 1 + 10 + 5 = 18 credits for one profile.

This is the endpoint you want when building an X researcher or lead-magnet. Pull the profile once, get bio + stats + 10 latest posts as one Markdown document. Your LLM can ingest it as context for a personalized outreach email or a competitive analysis.

H2-5: 5 Workflows That Actually Pay Off

Five patterns show up repeatedly in real LLM pipelines that touch tweet.md. The list is not exhaustive, but every one of these pays for a $5 credit pack in under an afternoon.

Workflow 1: RAG Ingestion From Curated Tweet Lists

The most common production use. You maintain a list of X post URLs on a topic (AI agent frameworks, indie hacker advice, industry research). On a cron, your script fetches each URL via /i/api/convert with thread=branch-8, splits on the per-post separators, embeds each post with your embedding model, and pushes them into your vector store. The Markdown output is already clean: no HTML stripping, no entity decoding, no JSON parsing. Your chunking logic can split on the # 1/N — Post by … headers tweet.md emits.

# Pseudo-pipeline
for url in curated_urls:
    md = requests.get(
        f"https://tweet.md/i/api/convert",
        params={"url": url, "thread": "branch-8", "userinfo": "author"},
        headers={"Authorization": f"Bearer {TWEETMD_API_KEY}"},
    ).text
    for chunk in split_on_post_headers(md):
        embed_and_store(chunk, metadata={"source": url})

Cost: 1 credit per post in the returned thread, plus 2 for the author. For 50 threads averaging 4 posts each, that is 50 + (50 × 2) = 150 credits — well inside the $5 pack.

Workflow 2: Citation Pulling For Long-Form Posts

You are writing a research-heavy Substack or LinkedIn long-form and you want to cite 10 specific X threads. For each cited thread, fetch the post URL with thread=ancestors to get the full reply chain, then quote the relevant excerpts. Because tweet.md returns Markdown with source URLs in the post headers, you have a ready-made citation format:

> Original post: https://x.com/exampleuser/status/9000000000000000001
> Captured: 2026-05-17T00:00:00.000Z
>
> Shipping notes: what changed in this release and why.

You can paste this block directly into your article with proper attribution. The timestamp is the capture time, not the original post time, but tweet.md also includes the original post time as a separate metadata field when you use userinfo=author.

Workflow 3: Agent Tool-Use (Claude Code / Cursor / skills.sh)

tweet.md publishes an official SKILL.md at github.com/tweet-md/skill that installs via npx skills add tweet-md/skill. The skill teaches the agent three patterns: (1) rewrite x.com and twitter.com URLs to tweet.md before fetching, (2) call /i/api/convert when it only has the full X URL, (3) call /i/api/profile when it needs bio context. Pair the skill with an API key in your agent's environment:

export TWEETMD_API_KEY=twmd_key_...

# In Claude Code / Cursor, the agent will now:
# - rewrite x.com/jack/status/20 → tweet.md/jack/status/20 when fetching
# - call /i/api/convert when it has the full URL
# - log credit usage from X-Tweetmd-Credits-Charged headers

Without the skill, an agent that encounters an x.com URL has three bad options: visit X directly (login wall + tracking), try to scrape the post (fragile, blocked by X's bot detection), or call a generic web fetcher (returns HTML, not Markdown, with ads and tracking pixels). With the skill, the agent rewrites the URL and gets a clean Markdown document in one HTTP call.

Workflow 4: Obsidian Vault Sync

The format=obsidian parameter wraps the same Markdown in YAML frontmatter. The frontmatter includes source, author, author handle, posted timestamp, captured timestamp, bio (for profiles), stats, and tags. The body is the post text and metadata you would get with the default markdown format.

---
source: https://x.com/jack/status/20
author: "jack"
author_handle: jack
posted: 2006-03-21T20:50:14.000Z
captured: 2026-05-17T00:00:00.000Z
tags: [x-post, tweetmd]
---

# X Post — jack — 2006-03-21
Post ID: 20
Source: https://x.com/jack/status/20
...

On a daily cron, your sync script walks a folder of saved X URLs, fetches each one with format=obsidian, and writes the result to your vault. Obsidian's Dataview plugin can then index posts by author, by tag, or by date. The frontmatter is the only thing that distinguishes this from a plain Markdown sync — if you want plain Markdown only, omit format.

Workflow 5: Apple Shortcuts On iOS

The prebuilt Shortcut installs from the tweet.md docs page and runs a single HTTP action. The key here is the x-ios-apikey header — tweet.md detects iOS-key requests and returns text/html with line breaks converted to <br>, which is what Shortcuts can copy into a note cleanly.

GET https://tweet.md/jack/status/20
Headers:
  x-ios-apikey: twmd_key_...

The Shortcut accepts Share Sheet input, falls back to Clipboard if you opened it directly, rewrites x.com to tweet.md in the URL, calls the endpoint with the iOS header, and copies the returned Markdown to your clipboard. From there you paste into Apple Notes, Obsidian Mobile, or any text-accepting app. The Shortcut stores your key locally; do not share a customized copy.

Save the threads that matter. ThreadGrab archives X threads as Markdown with media, correction tracking, and bulk export. tweet.md reads the post — ThreadGrab keeps it.

Try ThreadGrab

H2-6: Thread Scope Cheatsheet

The thread parameter is the most confusing part of the API. The four values map to four conversation scopes, and the -N suffix caps the response. Pick the smallest scope that gives your LLM the context it needs.

ScopeWhat comes backDefaultTypical use
offThe single post onlyFree tier forcedSingle quote, single citation
ancestorsThe post plus the reply chain above it up to the conversation rootReading a reply in full context
branchAncestors first, then replies underneath (sibling branches excluded)branch-15 (paid)RAG ingestion, citation pulling
allEntire conversation including sibling branchesTopic mapping, controversy analysis

The cap syntax is scope-N where N is 2-500 (default 20). branch-8 means: spend up to 8 posts on ancestors first, then replies below, no matter how long the thread actually is. If your post has 12 ancestors, branch-8 spends all 8 on the upward chain and ignores replies below. If your post has 3 ancestors, branch-8 spends 3 upward and 5 below. full and conversation are aliases for branch and all.

H2-7: format=markdown vs format=obsidian

The default markdown format returns the post body with stats, media, quotes, and full X Articles when present. It is what you want when feeding an LLM or saving to a plain-text note.

The obsidian format adds YAML frontmatter at the top: source, author, author_handle, posted, captured, optional bio for profiles, optional stats block, and tags. The body is identical to the markdown format. Use obsidian when you want Dataview queries on author or date, or when you want Obsidian's graph view to show connections between authors and topics.

Neither format returns JSON. tweet.md deliberately rejects format=json — the project philosophy is that Markdown is the canonical interchange format for LLM consumers, and JSON wrapping adds parsing overhead without adding value.

H2-8: Pricing Math — Which Pack to Buy

Three credit packs, $5 / $19 / $49. Cost per credit drops as pack size grows, but the dollar amount is the real decision. Here is the breakeven math.

PackCreditsPer-creditSingle-post fetchBranch-8 threadProfile dump
$5500$0.0100~500 fetches~62 fetches~31 dumps
$19 (best value)2,200$0.0086~2,200 fetches~275 fetches~138 dumps
$496,000$0.0082~6,000 fetches~750 fetches~375 dumps

"Single-post fetch" assumes thread=off and userinfo=off, so 1 credit per call. "Branch-8 thread" assumes 8 posts returned (8 credits) + 2 for author metadata = 10 credits per call. "Profile dump" assumes pinned + 10 latest + 5 replies = 18 credits per call (2 base + 1 pinned + 10 latest + 5 replies).

The $19 pack is the right starting point for most individual creators: 2,200 credits covers about 138 profile dumps or 275 branch-8 threads. The $49 pack is for teams running multiple daily crons or agents that ingest dozens of threads per day. The $5 pack is for smoke-testing the API before committing.

H2-9: When to Pair tweet.md With ThreadGrab

tweet.md and ThreadGrab are complementary, not competing. The short version: tweet.md reads the post, ThreadGrab saves the post.

Capabilitytweet.md APIThreadGrab
Read X posts as MarkdownYes (server-side render)Yes (export then read)
Single HTTP call per postYesNo (multi-step)
LLM-pipeline readyYes (text/markdown, no JSON)No (Markdown output, larger body)
Media files downloaded to diskNo (links only)Yes
Track post corrections over timeNoYes (re-fetch + diff)
Bulk archive a profile or listCredits-based, limitedYes (full export)
Export to Notion / GitHub / S3NoYes
Self-hostableNoNo (Cloud-hosted)
Pricing modelPer-creditSubscription / one-time

The natural division of labor: tweet.md for the read path and the agent loop (your LLM fetches a post, summarizes it, answers a question about it), ThreadGrab for the keep path (you find a thread worth preserving, you save it to your own storage with media and version history). Most active creators end up using both — tweet.md for the dozens of throwaway reads per day, ThreadGrab for the few threads per week that warrant a permanent copy.

FAQ

Is the tweet.md API free?

The free tier gives you 5 single-post requests per IP per calendar month with thread=off and userinfo=off forced on. That covers casual testing. Anything more (thread scopes beyond off, userinfo, profiles, X Articles) requires a paid API key. The smallest paid pack is $5 for 500 credits (1 credit per post returned, plus 2 credits per unique author when userinfo is enabled).

Can I use the tweet.md API from a Claude or ChatGPT agent?

Yes. tweet.md publishes a SKILL.md at github.com/tweet-md/skill that Claude Code, Cursor, and other agent runtimes install via npx skills add tweet-md/skill. The skill teaches the agent to rewrite x.com and twitter.com URLs to tweet.md before fetching, and to call /i/api/convert when it only has the full X URL. Pair the skill with an API key in your agent's env (TWEETMD_API_KEY) and the agent handles the rest.

How does the thread scope parameter work?

thread controls how much of the conversation comes back with the post you requested. thread=off returns just the single post (free tier). thread=ancestors returns the post plus its reply chain above it. thread=branch (default for paid: branch-15) returns ancestors first, then replies underneath. thread=all returns the entire conversation including sibling branches. Append -N to cap total posts (2-500, default 20). branch-8 means: fill ancestors up to 8, then replies below, no matter how long the thread actually is.

What does tweet.md return, JSON or Markdown?

Markdown, always. tweet.md explicitly rejects format=json. The response body is plain text/markdown with a heading, post metadata, and the post text. With format=obsidian you get YAML frontmatter wrapped around the same Markdown, suitable for direct import into an Obsidian vault. The credit cost and headers (X-Tweetmd-Posts-Returned, X-Tweetmd-Credits-Charged, X-Tweetmd-Thread-Cap, X-Tweetmd-Cap-Hit) are returned in HTTP headers, never appended to the body.

When should I use ThreadGrab instead of the tweet.md API?

Use the tweet.md API when you want clean Markdown for an LLM pipeline, a single-shot query, an agent loop, or an Obsidian import. Use ThreadGrab when you want to keep the thread: download the media files (images, video, screenshots) to your own disk, track post corrections over time, archive a full profile or list in bulk, or preserve a public statement as evidence with version history. tweet.md reads the post. ThreadGrab saves the post.