Quick Answer
TwexAPI の ツイート ID 別リプライ取得 endpoint(/twitter/tweets/{tweet_id}/replies/page)は、ツイート ID に対する元投稿、リプライのページ、ページネーション情報を返します。カーソルをたどる間は同じ sort_by を使います api.twexapi.io で Bearer 認証します。通常の read は 10 Credits(約 $0.10/1K)で、対象プランは 20+ QPS を公開しています。新規アカウントには 20,000 starting Credits が付与されます。詳細は本記事と https://docs.twexapi.io を参照してください。
FAQ
ツイート ID 別リプライ取得 エンドポイントは何を返しますか?
ツイート ID に対する元投稿、リプライのページ、ページネーション情報を返します。カーソルをたどる間は同じ sort_by を使います
リプライ取得で使える並び順とページネーション項目は?
リクエストでは sort_by に Recency、Relevance、Likes を指定でき、2 ページ目以降は next_cursor を渡します。レスポンスには root_tweet、リプライの data、has_next_page、next_cursor が含まれます。ページ取得中はツイート ID と並び順を変更しません。
リプライスレッドの取得時に何を保存すべきですか?
元投稿は 1 回だけ保存し、元のリプライ行、tweet_id、指定した sort_by、ページ番号、送受信したカーソル、取得日時を記録します。リプライはツイート ID で重複を除き、各ページの成功後にカーソルを保存します。
この用途で公式 X API ではなく TwexAPI を使う理由は?
ツイート ID 別リプライ取得 では https://docs.twexapi.io に記載された TwexAPI Bearer workflow を利用できます。通常の Post/Profile read は 10 Credits(約 $0.10/1K)で、対象プランは 20+ QPS を公開しています。新規アカウントには 20,000 starting Credits が付与されます。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
TwexAPI でこのワークフローのコストは?
通常の読み取りは約 10 Credits です。公開換算では 1,000 回で 10,000 Credits(約 $0.10)、10,000 回で約 100,000 Credits です。実際の cost は endpoint ごとに異なるため https://twexapi.io/pricing を確認してください。
リプライは、投稿が会話へ変わる場所です。ローンチ反応、コミュニティの反応、モデレーションレビュー用データを扱うなら、root tweet だけでは足りません。必要なのは、リプライ、取得時の並び順、そしてデータセットがどのように収集されたかを説明できる cursor の履歴です。
新しい実装では、TwexAPI のページング対応リプライエンドポイント POST /twitter/tweets/{tweet_id}/replies/page を使います。リプライをページ単位で返すため、大きなスレッドを 1 回で取得しようとしてタイムアウトするリスクを避けやすくなります。
エンドポイントとソート
Answer: エンドポイントとソートとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
POST リクエストを次の URL に送ります。
https://api.twexapi.io/twitter/tweets/<tweet_id>/replies/pagepath パラメータは root tweet の ID です。JSON 本文では次を指定できます。
| フィールド | 必須 | 使い方 |
|---|---|---|
sort_by | いいえ | Recency、Relevance、Likes。1 回のエクスポートでは同じ sort mode を使い続けます。 |
next_cursor | いいえ | 初回は空にします。次ページでは前回レスポンスの next_cursor を渡します。 |
最初のページには root_tweet と最初のリプライ一覧 data が含まれることがあります。後続ページでは、さらにリプライ、has_next_page、next_cursor が返ります。
最初のページを取得する
Answer: 最初のページを取得するとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
時系列に近いエクスポートが必要なら Recency を使います。Relevance や Likes は、ランキング自体が分析対象のときに使います。
curl --request POST \
--url https://api.twexapi.io/twitter/tweets/<tweet_id>/replies/page \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sort_by": "Recency"
}'簡略化したレスポンスは次のようになります。
1{
2 "code": 200,
3 "msg": "success",
4 "root_tweet": {
5 "tweet_id": "1803006263529541838",
6 "text": "<root tweet text>"
7 },
8 "data": [
9 {
10 "tweet_id": "1234567890123456789",
11 "text": "<reply text>",
12 "created_at": "Mon Jul 01 12:34:56 +0000 2025",
13 "user": {
14 "screen_name": "example_user"
15 }
16 }
17 ],
18 "has_next_page": true,
19 "next_cursor": "cursor_from_this_response"
20}next_cursor で続きへ進む
Answer: next_cursor で続きへ進むとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
has_next_page が true の場合は、cursor を次のリクエストに渡します。ページング中は同じ tweet_id と sort_by を維持してください。
curl --request POST \
--url https://api.twexapi.io/twitter/tweets/<tweet_id>/replies/page \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sort_by": "Recency",
"next_cursor": "cursor_from_this_response"
}'途中で sort mode を変えると、結果を説明しにくくなります。別のランキング視点が必要なら、別のエクスポートとして実行し、明確にラベルを付けます。
Python エクスポートスクリプト
Answer: Python エクスポートスクリプトとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
次のスクリプトは、リプライを JSONL に書き出し、root tweet を 1 回だけ保存し、tweet_id で重複排除し、監査用の page メタデータを保存します。
1import json
2import time
3from datetime import datetime, timezone
4from pathlib import Path
5
6import requests
7
8TOKEN = "<your_bearer_token>"
9TWEET_ID = "<tweet_id>"
10SORT_BY = "Recency"
11URL = f"https://api.twexapi.io/twitter/tweets/{TWEET_ID}/replies/page"
12REPLIES_OUT = Path(f"{TWEET_ID}-replies.jsonl")
13ROOT_OUT = Path(f"{TWEET_ID}-root.json")
14META_OUT = Path(f"{TWEET_ID}-replies-meta.json")
15
16headers = {
17 "Authorization": f"Bearer {TOKEN}",
18 "Content-Type": "application/json",
19}
20
21cursor = None
22page_number = 0
23seen_reply_ids = set()
24page_log = []
25
26with REPLIES_OUT.open("w", encoding="utf-8") as replies_file:
27 while True:
28 payload = {"sort_by": SORT_BY}
29 if cursor:
30 payload["next_cursor"] = cursor
31
32 response = requests.post(URL, headers=headers, json=payload, timeout=30)
33 response.raise_for_status()
34 body = response.json()
35
36 page_number += 1
37
38 if page_number == 1 and body.get("root_tweet"):
39 ROOT_OUT.write_text(
40 json.dumps(body["root_tweet"], ensure_ascii=False, indent=2),
41 encoding="utf-8",
42 )
43
44 replies = body.get("data") or []
45 for reply in replies:
46 reply_id = reply.get("tweet_id") or reply.get("id")
47 if not reply_id or reply_id in seen_reply_ids:
48 continue
49 seen_reply_ids.add(reply_id)
50 replies_file.write(json.dumps(reply, ensure_ascii=False) + "\n")
51
52 page_log.append({
53 "page": page_number,
54 "items": len(replies),
55 "has_next_page": body.get("has_next_page"),
56 "next_cursor": body.get("next_cursor"),
57 })
58
59 if not body.get("has_next_page") or not body.get("next_cursor"):
60 break
61
62 cursor = body["next_cursor"]
63 time.sleep(1)
64
65META_OUT.write_text(json.dumps({
66 "tweet_id": TWEET_ID,
67 "sort_by": SORT_BY,
68 "exported_at": datetime.now(timezone.utc).isoformat(),
69 "unique_replies": len(seen_reply_ids),
70 "pages": page_log,
71}, ensure_ascii=False, indent=2), encoding="utf-8")
72
73print(f"Saved {len(seen_reply_ids)} replies to {REPLIES_OUT}")定期ジョブでは、各ページの取得に成功するたびに最後の cursor を保存します。失敗しても、すでに収集したページを捨てずに再開できます。
保存しておきたいフィールド
Answer: 保存しておきたいフィールドとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
最低限、次を保存します。
- 生の reply オブジェクト。
tweet_id、created_at、本文、作者フィールド、レスポンスに含まれるエンゲージメント数。- 返却される場合は
in_reply_to、reply_to、conversation_id、関連 thread フィールド。 - root
tweet_id、sort_by、エクスポート時刻、ページ番号、cursor メタデータ。 https://x.com/i/web/status/<reply_id>のような正規化済み reply URL。
正規化済み行だけでなく、raw data も残します。reply schema は変わることがあり、後続分析で想定外のフィールドが必要になることもあります。
分析時の注意
Answer: 分析時の注意とは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
リプライエクスポートは次に役立ちます。
- プロダクトやキャンペーン公開直後の反応を測る。
- アナウンス後の顧客の懸念を確認する。
- 特定投稿を中心にモデレーションキューを作る。
- 時系列順といいね順で議論の見え方がどう変わるか比較する。
- 感情分析やトピックモデリングの前に、手動ラベル用のサンプルを作る。
リプライデータを完全な世論調査として扱わないでください。リプライはランキング、削除、アカウント可視性、返信する人の偏りに影響されます。データセットの限界が見えるよう、十分な文脈を保存します。
よくある落とし穴
Answer: よくある落とし穴とは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 10 Credits(約 $0.10/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。
- 最初の 1 ページだけを取得して、会話全体として扱う。
- ページング途中で
sort_byを変える。 root_tweetを捨ててしまい、リプライデータセットの文脈を失う。- 言語判定や手動確認なしに感情分析を実行する。
- タイムスタンプなしでエンゲージメント数を上書きする。
まとめ
リプライ収集では、POST /twitter/tweets/{tweet_id}/replies/page を使い、sort_by を固定し、next_cursor で続きのページを取得し、root tweet と raw reply 行を保存します。1 回の固定件数リクエストより、監査、再試行、説明がしやすい流れになります。