Find the post ID
Copy the number at the end of an X status URL. In x.com/user/status/1897412345678901234, the post ID is 1897412345678901234.
Use the thread route for the wider conversation. The replies route returns direct replies to one post.
Request the Twitter thread as JSON
Moderate responses use stable field names. Contentful responses are smaller and work well in an AI context window.
curl "https://twitterxapi.com/api/v1/posts/1897412345678901234/thread?level=moderate" \
-H "Authorization: Bearer $TWITTERXAPI_KEY"{
"items": ["..."],
"count": 20,
"pagination": {
"next_cursor": "DAABCgAB...",
"has_more": true
}
}Save every thread page
Collect each page and pass its next cursor into the following request.
import json, os, requests
post_id = "1897412345678901234"
url = f"https://twitterxapi.com/api/v1/posts/{post_id}/thread"
headers = {"Authorization": f"Bearer {os.environ['TWITTERXAPI_KEY']}"}
items, cursor = [], None
while True:
params = {"level": "moderate"}
if cursor: params["cursor"] = cursor
r = requests.get(url, headers=headers, params=params, timeout=60)
r.raise_for_status()
page = r.json(); items.extend(page["items"])
cursor = page["pagination"]["next_cursor"]
if not page["pagination"]["has_more"] or not cursor: break
with open(f"thread-{post_id}.json", "w") as f:
json.dump(items, f, indent=2, ensure_ascii=False)Preserve the conversation
Keep each post ID, conversation ID, author, and reply relationship fields. Sorting only by time can flatten parallel reply branches into the wrong sequence.
COMMON QUESTIONS
Frequently asked questions
What is the difference between a thread and replies?+
The thread route reads the wider conversation. The replies route focuses on direct replies.
Can I get a full Twitter thread as JSON?+
Yes. Follow next_cursor until has_more becomes false.
Can I send the thread to an AI model?+
Yes. The contentful response level reduces the data to text and useful context.
TRY THE API
Make the first request today.
One key covers REST and MCP. Add credit when you need it.
Get an API key