How to Download All Posts and Replies to CSV/Excel (Complete Guide)

Author:TwexAPI Team
EN
Read in:
English
日本語中文
Download public social data
Export Posts to CSV
Export Posts to Excel
public social platform Comment Scraper
public social platform Thread Downloader
Python
TwexAPI

Step-by-step tutorial on downloading all public social platform posts, comments, and replies to CSV or Excel. Use TwexAPI pagination to export historical archives without rate limits.

Quick Answer

Downloading all posts and replies for a user means paginating the documented TwexAPI timeline and reply endpoints until the cursor is exhausted. Save each raw page and cursor checkpoint, deduplicate by post ID, and estimate Credits from the actual endpoint before a large JSON or CSV export.

FAQ

Why use TwexAPI instead of the first-party developer API for this workflow?

For full timeline export, TwexAPI provides Bearer-authenticated workflows documented at https://docs.twexapi.io. A typical post or profile read uses 5 Credits (about $0.05 per 1,000 under the published conversion), and qualifying paid plans publish 20+ QPS. New accounts receive 20,000 starting Credits. As of 2026-08-20, first-party developer API Post reads list at $5 per 1,000 resources and User reads at $10 per 1,000; official rate limits vary by endpoint and access level.

How much does this API workflow cost on TwexAPI?

A typical read uses about 5 Credits. Under the published conversion, 1,000 such reads use 5,000 Credits, or about $0.05; a 10,000-read job uses about 50,000 Credits. Actual costs vary by endpoint, so confirm the endpoint price and current plan at https://twexapi.io/pricing.

Downloading a user's X history is not just "ask for a big number and hope the response finishes." Large exports need a cursor loop, a place to save raw results, and a small amount of bookkeeping so retries do not create duplicate rows.

This guide uses TwexAPI's paginated endpoint, POST /twitter/tweets-replies/page, to export a user's own posts and replies one page at a time. It is a better default for archives, research, compliance review, and repeatable data jobs than a single count-based request.

Export Strategy

Answer: Export Strategy means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 5 Credits (about $0.05 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-20, first-party developer API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.

The safest export has two files:

  • Raw JSONL: one tweet object per line, kept as the source of truth.
  • CSV projection: a smaller table for spreadsheets, BI tools, or annotation.

Keep both. The CSV is easier to review, but the raw JSON keeps fields you may need later, such as media, quotes, reply metadata, or author verification fields.

API Endpoint

Answer: API Endpoint is implemented by calling the TwexAPI endpoint documented in this guide with a Bearer Token; batch or paginated requests reduce overhead to ~5 credits per call at 20+ QPS.

POST https://api.twexapi.io/twitter/tweets-replies/page

Authorization: Bearer <your_token>
Content-Type: application/json

Request body:

FieldRequiredDescription
screen_nameYesTarget X username, with or without @
next_cursorNoCursor returned by the previous page

Each response includes the current data array plus pagination metadata:

FieldMeaning
dataCurrent page of tweets and replies
has_next_pageWhether another page is available
next_cursorCursor to pass into the next request

The first request does not include next_cursor:

curl --request POST \
  --url https://api.twexapi.io/twitter/tweets-replies/page \
  --header 'Authorization: Bearer <your_token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "screen_name": "elonmusk"
  }'

To continue, send the returned cursor:

{
  "screen_name": "elonmusk",
  "next_cursor": "1234567890"
}

Python Cursor Export

Answer: Python Cursor Export means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 5 Credits (about $0.05 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-20, first-party developer API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.

The script below writes raw pages to tweets-replies.jsonl. It deduplicates by tweet_id, stops when has_next_page is false, and keeps the cursor loop explicit so it is easy to resume or debug.

1import json
2import os
3import time
4
5import requests
6
7API_URL = "https://api.twexapi.io/twitter/tweets-replies/page"
8TOKEN = os.environ["TWEXAPI_TOKEN"]
9SCREEN_NAME = "elonmusk"
10OUTPUT_PATH = "tweets-replies.jsonl"
11
12def fetch_page(next_cursor=None):
13    body = {"screen_name": SCREEN_NAME}
14    if next_cursor:
15        body["next_cursor"] = next_cursor
16
17    response = requests.post(
18        API_URL,
19        headers={
20            "Authorization": f"Bearer {TOKEN}",
21            "Content-Type": "application/json",
22        },
23        json=body,
24        timeout=45,
25    )
26    response.raise_for_status()
27    payload = response.json()
28    if payload.get("code") not in (None, 200):
29        raise RuntimeError(payload.get("msg", "TwexAPI request failed"))
30    return payload
31
32seen_ids = set()
33next_cursor = None
34page_count = 0
35saved_count = 0
36
37with open(OUTPUT_PATH, "w", encoding="utf-8") as output:
38    while True:
39        payload = fetch_page(next_cursor)
40        page_count += 1
41
42        items = payload.get("data") or []
43        for tweet in items:
44            if not tweet:
45                continue
46
47            tweet_id = tweet.get("tweet_id") or tweet.get("id")
48            if not tweet_id or tweet_id in seen_ids:
49                continue
50
51            seen_ids.add(tweet_id)
52            output.write(json.dumps(tweet, ensure_ascii=False) + "\n")
53            saved_count += 1
54
55        print(f"page={page_count} fetched={len(items)} saved={saved_count}")
56
57        if not payload.get("has_next_page") or not payload.get("next_cursor"):
58            break
59
60        next_cursor = payload["next_cursor"]
61        time.sleep(0.5)
62
63print(f"Finished: {saved_count} unique tweets and replies saved to {OUTPUT_PATH}")

Run it with:

TWEXAPI_TOKEN="your_twexapi_bearer_token" python export-tweets-replies.py

Create A CSV Projection

Answer: Create A CSV Projection means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 5 Credits (about $0.05 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-20, first-party developer API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.

After saving raw JSONL, create a smaller CSV with the fields your team actually reviews.

1import csv
2import json
3
4INPUT_PATH = "tweets-replies.jsonl"
5OUTPUT_PATH = "tweets-replies.csv"
6
7fields = [
8    "tweet_id",
9    "created_at_datetime",
10    "text",
11    "lang",
12    "favorite_count",
13    "retweet_count",
14    "reply_count",
15    "quote_count",
16    "view_count",
17    "in_reply_to",
18    "in_reply_to_screen_name",
19    "is_quote_status",
20]
21
22with open(INPUT_PATH, encoding="utf-8") as source, open(
23    OUTPUT_PATH, "w", encoding="utf-8", newline=""
24) as target:
25    writer = csv.DictWriter(target, fieldnames=fields)
26    writer.writeheader()
27
28    for line in source:
29        tweet = json.loads(line)
30        row = {field: tweet.get(field) for field in fields}
31        row["tweet_id"] = tweet.get("tweet_id") or tweet.get("id")
32        row["text"] = tweet.get("full_text") or tweet.get("text") or ""
33        writer.writerow(row)
34
35print(f"Wrote {OUTPUT_PATH}")

Fields To Preserve

Answer: Fields To Preserve means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 5 Credits (about $0.05 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-20, first-party developer API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.

For research or audit work, do not keep only text. Store enough context to explain the row later.

FieldWhy it matters
tweet_idStable deduplication and citation key
created_at / created_at_datetimeTimeline ordering and time-window analysis
text / full_textHuman-readable content
in_reply_to, in_reply_to_screen_nameSeparates replies from standalone posts
favorite_count, retweet_count, reply_count, quote_countInteraction review
media, urls, hashtags, cashtagsContent enrichment
userAuthor snapshot at export time

Production Notes

Answer: Production Notes means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 5 Credits (about $0.05 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-20, first-party developer API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.

  • Save each page as it arrives. Do not wait until the full export finishes.
  • Store the last successful next_cursor if you need resumable jobs.
  • Deduplicate by tweet_id; retries and cursor changes can otherwise create repeated rows.
  • Keep raw JSONL even when the CSV is all you need today.
  • Record the export time, target screen_name, and script version with the output files.
  • For recurring exports, compare new rows against previously saved tweet_id values.

Count Endpoint Or Page Endpoint?

Answer: Count Endpoint Or Page Endpoint? is implemented by calling the TwexAPI endpoint documented in this guide with a Bearer Token; batch or paginated requests reduce overhead to ~5 credits per call at 20+ QPS.

TwexAPI also exposes GET /twitter/{screen_name}/tweets-replies/{count}. It can be convenient for small one-off pulls where you know the target count.

For serious exports, use POST /twitter/tweets-replies/page. Cursor pagination makes progress visible, lowers the cost of a failed request, and gives you better control over storage and retries.

Related Resources

How to Download All Posts and Replies to CSV/Excel (Complete Guide)