本文へスキップ

ツイート ID を X から一括でリハイドレートする方法

ツイート ID をリハイドレートするには、100件ずつ API の ID 指定取得エンドポイントに送り、返ってきたツイートを保存します。100万 ID なら10,000回の呼び出しで、削除済みや非公開のツイートは何も返りません。

結論: リハイドレートとは、ツイート ID を、本文、日時、メトリクス、投稿者を含む完全なツイートに戻すことです。公式 X API は1回の呼び出しで100 ID を取得できますが、1投稿あたり$0.005、100万件で$5,000かかり、月300万件が上限です。Sorsa API の POST /tweet-info-bulk は1リクエストで100 ID を受け付け、100万件あたり$14からです。100回分の無料リクエストで、最初の10,000 ID をカバーできます。

エンドポイント
POST /tweet-info-bulk
1リクエストの件数
100 ID
料金
1,000件あたり$0.014から

#ツイート ID のリハイドレートとは

ツイート ID のリハイドレートとは、各 ID をもう一度引いて、その裏にある完全なツイートを取得することです。本文、投稿時刻、いいね数と閲覧数、投稿者のプロフィールが含まれます。ツイート ID とは、投稿のリンクの末尾にある19桁の数字のことで、それを並べたリストは dehydrated(ID だけに縮めた)データセットと呼ばれます。1件の ID がいつ投稿されたかを、リクエストを使う前に調べるには、無料のツイート ID の日付変換ツールに貼り付けてください。

データセットが ID だけの形で出回るのは、X の規約があるからです。X 開発者ポリシー(新しいタブで開きます)は、投稿 ID とユーザー ID を他者と共有することは認めていますが、ツイート本体の共有は認めておらず、X の書面による許可なしに1人の受け手へ渡せるのは30日あたり150万件の投稿 ID までと上限を定めています。そのため、実際に目にするリストのほとんどは数字だけです。

  • 研究用アーカイブ。 Harvard Dataverse、Zenodo、GitHub にある選挙、危機、COVID-19 のコレクションは、数千万行に及ぶこともある ID のテキストファイルで配布されます。
  • ソーシャルリスニングのエクスポート。 たとえば Meltwater の API は、X の投稿を ID と投稿者 ID だけでエクスポートし、顧客にリハイドレートするよう案内しています(新しいタブで開きます)。
  • 自分の記録。 ID だけを残して本文を落とした、古いデータベース、ログ、スプレッドシート。

リハイドレートが返すのは、現在のツイートです。収集後に削除された投稿や、非公開になった、または凍結されたアカウントの投稿は空で返ります。得られるメトリクスと投稿者プロフィールも、投稿した日の値ではなく現在の値です。そのため、リハイドレートした結果は、元のリストより必ず少し小さくなります。

#費用と所要時間

100万件のツイート ID のリハイドレートは、公式 X API では$5,000、Sorsa API では$14からです。どちらも1回の呼び出しで100 ID を取得します。違うのは課金の単位です。X の料金表(新しいタブで開きます)は返した投稿1件ごとに$0.005を課金しますが、Sorsa API は中身にかかわらず、100件のバッチ1つにつき1リクエストを課金します。

大きなリストでの公式 X API の料金には、さらに2つのルールが影響します。従量課金は、請求サイクルあたり300万投稿の読み取りで止まります。それより大きなリストは、翌月まで待つか、月約$42,000からの Enterprise 契約が必要です。そして2026年11月22日からは、X がexpansions で付いてくるすべてのオブジェクトに課金します(新しいタブで開きます)。要求した投稿者プロフィール1件ごとに、投稿の$0.005に$0.010が加算されます。

ツイート IDSorsa API毎秒20リクエストでの Sorsa API の所要時間公式 X API
10K無料(登録時の100リクエスト)約5秒$50
100K$1.40から1分未満$500
1M$14から約8分$5,000
3M$42から約25分$15,000(月間上限のすべて)
10M$140から約1時間23分Enterprise のみ、月$42K以上
  • 10K

    Sorsa API
    無料(登録時の100リクエスト)
    毎秒20リクエストでの Sorsa API の所要時間
    約5秒
    公式 X API
    $50
  • 100K

    Sorsa API
    $1.40から
    毎秒20リクエストでの Sorsa API の所要時間
    1分未満
    公式 X API
    $500
  • 1M

    Sorsa API
    $14から
    毎秒20リクエストでの Sorsa API の所要時間
    約8分
    公式 X API
    $5,000
  • 3M

    Sorsa API
    $42から
    毎秒20リクエストでの Sorsa API の所要時間
    約25分
    公式 X API
    $15,000(月間上限のすべて)
  • 10M

    Sorsa API
    $140から
    毎秒20リクエストでの Sorsa API の所要時間
    約1時間23分
    公式 X API
    Enterprise のみ、月$42K以上
ツイート ID

公式 X API

$5,000

1M件のツイート ID をリハイドレートする場合

1投稿あたり$0.005

Sorsa API

$14から

1M件のツイート ID をリハイドレートする場合

1,000件あたり$0.014から

250分の1のコスト

Sorsa API の「から」の価格は、リクエストあたりの最低レートで計算しています。Pro プランのレートなら、100万 ID は$19.90です。失敗したリクエストに課金されることはなく、投稿者のプロフィール全体が、すべてのツイートに追加料金なしで付いてきます。検索で新しく収集する場合の同じ比較は、100万ツイートの費用をご覧ください。

#Sorsa API でツイート ID をリハイドレートする

ツイート ID を大規模にリハイドレートするには、Twitter(X)API 兼スクレイピングツールである Sorsa API を使います。POST /tweet-info-bulk(新しいタブで開きます) は、1リクエストで最大100件の ID または投稿リンクを受け付け、各ツイートを投稿者のプロフィール全体付きで返します。料金は1,000 ID あたり$0.014から、どのプランでも毎秒20リクエストです。必要なのは API キー1つで、X の開発者アカウントも OAuth も不要、X のログイン情報も求めません。

  1. キーを取得する。 サインアップして、ダッシュボードから API キーをコピーします。100回分の無料リクエストで、最大10,000 ID をリハイドレートできます。

  2. バッチを送る。 tweet_links 配列に、最大100件の ID を文字列で入れます。投稿の完全なリンクでも使えます。

    ターミナル
    curl -X POST "https://api.sorsa.io/v3/tweet-info-bulk" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"tweet_links": ["1856270992012337728",
           "1399991672632369728", "1496699442164785728"]}'
    
  3. ツイートを読む。 レスポンスは tweets 配列1つで、ページネーションはありません。各ツイートが自身の id を持つので、送った ID との突き合わせに使えます。

    レスポンス200 OK
    {
      "tweets": [
        {
          "id": "1856270992012337728",
          "full_text": "Day 3 of the field survey: river levels are normal.",
          "created_at": "2024-11-12T09:41:07Z",
          "lang": "en",
          "likes_count": 42,
          "retweet_count": 7,
          "reply_count": 3,
          "quote_count": 1,
          "view_count": 5210,
          "bookmark_count": 2,
          "conversation_id_str": "1856270992012337728",
          "is_reply": false,
          "is_quote_status": false,
          "user": {
            "id": "1497281610093821952",
            "username": "field_notes_demo01",
            "display_name": "Field Notes Demo",
            "followers_count": 1288,
            "protected": false,
            "verified": false
          }
        }
      ]
    }
    

403 はキーがないか、リクエストを使い切った場合、429 は1秒に20リクエストを超えた場合です。1秒待ってから、バッチをもう一度送ってください。引用とリポストには元のツイートが入れ子で含まれ(quoted_status、retweeted_status)、返信は in_reply_to_tweet_id で返信先のツイートを示し、メディアのリンクは entities に入っています。

知っておきたいこと

リハイドレートで得られるメトリクスは、現在の数字です。2016年のツイートも、今のいいね数と閲覧数、そして投稿者の現在の名前、プロフィール、フォロワー数で返ってきます。投稿日時点の値が必要な研究なら、元のデータセットに保存されているカウントがあれば、それを使ってください。

#リクエストを使う前に ID リストを整える

リハイドレートの失敗の多くは、API ではなく ID ファイルで起きています。ツイート ID は19桁で、スプレッドシートや64ビット浮動小数点が保持できる桁数を超えています。そのため、Excel、float 列のある pandas、JavaScript の JSON.parse を通ったリストは、存在しないツイートを指すようになります。24,000件中18件しか取得できなかったという Stack Overflow の有名な質問も、原因は API ではなく、壊れた ID リストでした。

データセット内のID 1856270992012337728 スプレッドシートで開いて保存 1856270992012340000 15桁を保持 JSON.parseやfloat列で数値として読むと 1856270992012337664 2^53を超えて丸められる
スプレッドシートは15桁、浮動小数点は約16桁しか保持できないため、19桁のツイート ID は末尾の桁を失い、ツイートを指さなくなる。

リストを壊さないためのルールは3つです。

  • ID はテキストとして読む。 pandas なら pd.read_csv(path, dtype=str)、JSON ファイルなら id_str か文字列形式を使います。生のファイルを Excel で開いてはいけません。
  • 先に重複を削除する。 共有されたデータセットでは、日ごとのファイルにまたがって ID が重複していることがよくあります。重複は、100件のバッチの枠を無駄にします。
  • 丸められた行を見つける。 指数表記の ID(1.85627E+18)や、末尾にゼロが並ぶ ID は、スプレッドシートで切り捨てられたものです。そうした行は元のデータ提供元から取り直してください。どの API でも修復できません。

下のプランナーは、リストのサンプルに対してこれらのチェックをブラウザ上で実行し、ジョブ全体の費用を試算します。

チェックはブラウザ内で実行されます。外部には何も送信されません。

使えるID

4

除外した重複

1

丸めで壊れたID

2

最古と最新の投稿日

2020年3月14日、2024年11月12日

2行がスプレッドシートで丸められたようです(1.85627E+18、1156897366733870000)。元のデータからテキストとして再出力してください。丸められたIDは、どのツイートも指しません。

IDリスト全体の件数

Sorsa API

最安 $14

1リクエストにつき100件のID、各ツイートに投稿者情報を含む

約8分(毎秒20リクエスト)

Official X API

$5,000

1ポストあたり$0.005、2026年11月22日からは返された投稿者1人あたり$0.010を追加

リストの一部を貼り付けると、重複と丸められたIDを検出できます。そのあと全体の件数を選ぶと、料金と所要時間が表示されます。

#数百万件のツイート ID を処理する再開可能なジョブ

数百万件の ID のリストには、フルレートで動き、クラッシュしても二重に課金されずに済むジョブが必要です。以下のスクリプトは、ID をテキストとして読み込み、重複を削除し、毎秒100件のバッチを20回送り、届いたツイートを順次書き出し、完了したバッチを progress.txt に記録します。再実行すれば、前回止まった場所から始まります。

IDファイル tweet_ids.txt データセット、 書出し、旧ログ クリーンアップ テキスト読込 重複を除去 100件ずつに分割 POST /tweet-info-bulk 1リクエストでID 100件 最大で毎秒 20リクエスト tweets.jsonl ツイートと投稿者 missing_ids.txt 取得できなかった分 回収率 = 返ったツイート数 ÷ 送信した重複なしID数
一度整えてから、100件のバッチを毎秒20回送り、出力をツイートと欠落 ID に分ける。2つのファイルから回収率が分かる。
rehydrate.py
import json
import os
import time
from concurrent.futures import ThreadPoolExecutor

import requests

URL = "https://api.sorsa.io/v3/tweet-info-bulk"
HEADERS = {"ApiKey": os.environ.get("SORSA_API_KEY", "YOUR_API_KEY")}
BATCH, PER_SECOND = 100, 20


def load_ids(path):
    seen, ids = set(), []
    with open(path, encoding="utf-8") as f:
        for line in f:
            tid = line.strip().split("/status/")[-1].split("?")[0]
            if tid.isdigit() and tid not in seen:
                seen.add(tid)
                ids.append(tid)
    return ids


def lookup(batch):
    for attempt in range(5):
        r = requests.post(URL, headers=HEADERS, timeout=60,
                          json={"tweet_links": batch})
        if r.status_code == 429 or r.status_code >= 500:
            time.sleep(2 ** attempt)
            continue
        if r.status_code == 404:
            return []
        r.raise_for_status()
        return r.json().get("tweets", [])
    raise RuntimeError(f"batch starting {batch[0]} failed 5 times")


def run(ids):
    batches = [ids[i:i + BATCH] for i in range(0, len(ids), BATCH)]
    start = 0
    if os.path.exists("progress.txt"):
        start = int(open("progress.txt").read() or 0)
    with open("tweets.jsonl", "a", encoding="utf-8") as out, \
         open("missing_ids.txt", "a", encoding="utf-8") as miss, \
         ThreadPoolExecutor(max_workers=PER_SECOND) as pool:
        for k in range(start, len(batches), PER_SECOND):
            t0 = time.monotonic()
            group = batches[k:k + PER_SECOND]
            for batch, tweets in zip(group, pool.map(lookup, group)):
                got = {t["id"] for t in tweets}
                for t in tweets:
                    out.write(json.dumps(t, ensure_ascii=False) + "\n")
                for tid in batch:
                    if tid not in got:
                        miss.write(tid + "\n")
            out.flush()
            miss.flush()
            with open("progress.txt", "w") as p:
                p.write(str(k + len(group)))
            time.sleep(max(0, 1 - (time.monotonic() - t0)))


if __name__ == "__main__":
    ids = load_ids("tweet_ids.txt")
    run(ids)
    with open("tweets.jsonl", encoding="utf-8") as f:
        got = {json.loads(line)["id"] for line in f}
    print(f"recovered {len(got):,} of {len(ids):,} IDs "
          f"({len(got) / len(ids):.1%})")

キーは export SORSA_API_KEY=... で設定し、tweet_ids.txt に1行ずつ ID か投稿リンクを入れて、python rehydrate.py を実行します。毎秒20リクエストなら、100万 ID は約8分、1,000万 ID は1時間半足らずで終わります。長時間の実行の前に、GET /key-usage-info(新しいタブで開きます) でキーの残りリクエスト数を確認してください。このチェックは無料です。

#一部のツイートが返ってこない理由

ツイート ID が何も返さないのは、そのツイートがもう一般には存在しないときです。投稿者が削除した、アカウントが非公開になった、アカウントが凍結または無効化された、のいずれかです。どの API でもこれらは復元できません。何も返らない ID はエラーではなく1つの答えなので、スクリプトは missing_ids.txt に書き出して先に進みます。

どれだけ欠落するかは、リストの古さと話題によって変わります。先月集めたセットはほぼ完全に戻ることがありますが、選挙、紛争、スパムの多いハッシュタグに関する何年も前のセットは、それらのアカウントが凍結されたり削除したりする頻度が高いため、はるかに多く失われます。推測せず、測定してください。

  • 回収率。 返ってきたツイート数を、送った一意の ID 数で割った値で、スクリプトが最後に出力する行です。同じリストでも年ごとに返るツイートが減るので、リハイドレートした日付とあわせて報告してください。
  • 期間別の欠落。 欠落した ID の日付をデコードして(上のプランナーと ID の日付変換ツールのどちらでも読めます)、損失が特定の1週間や1つの出来事に集中していないかを確認します。
  • 壊れたのか、消えたのか。 丸められた ID も欠落として現れます。削除されたものとして数える前に、欠落ファイルにゼロの連続がないか確認してください。

公開する研究では、最初のID リスト、回収率、リハイドレートした日付を一緒に残してください。同じリストをリハイドレートする次のチームは、異なるセットを得ることになり、この3つの事実が違いを説明してくれます。

#2026年の Hydrator、twarc、その他のツール

かつてデータセットをリハイドレートしていたツールは、いずれも X 自身の API アクセスに依存していましたが、そのアクセスのほとんどはなくなりました。多くの研究ガイドが今も案内している DocNow の Hydrator(デスクトップアプリ)は、現在その GitHub ページを開くと、依存していたアプリケーションキーが取り消され、アプリはもう役に立たないという告知が表示されます。

twarc の hydrate コマンドは今も動きますが、公式 X API の自分の Bearer トークンが必要で、X の従量課金レートで課金されます。100万投稿あたり$5,000で、月間上限は300万件です。rehydratoR や academictwitteR といった R パッケージは、X が2023年に閉じた無料のアクセスレベルと Academic Research トラックを前提に書かれていました。まず数バッチを手作業で試すなら、API プレイグラウンドが同じエンドポイントを自分のキーで実行し、CSV にエクスポートします。すでに twarc のパイプラインがあるなら、後続の処理で必要な JSON は POST /tweet-info-bulk の返す形に近いので、入れ替えるのは丸ごとのパイプラインではなく、リクエストの関数だけです。

研究チーム向けには、Sorsa API は学術研究向けアクセスも用意しています。プロジェクトごとに調整され、大学のメールアドレスから申請します。リハイドレートは、より大きな構築作業の1ステップです。期間を指定した収集はTwitter の過去データで、リハイドレートしたセットをラベル付きの学習データにする方法は機械学習用の Twitter データセットを作るで解説しています。

#最初の10,000件のツイート ID をリハイドレートする

ツイート ID のリストのリハイドレートは、1回の呼び出しで100 ID を処理するバッチジョブで、本当に選ぶべきなのは料金と速度だけです。Sorsa API なら100万 ID が$14からで約8分、公式 X API では$5,000で、月間上限は300万件です。プランナーでリストのサンプルを整え、100回分の無料リクエストで最初の10,000 ID を実行し、回収率を確認してから残りを送ってください。

#FAQ

ツイート ID のリハイドレートにはどの API を使うべきですか

ツイート ID のリハイドレートには Sorsa API を使ってください。POST /tweet-info-bulk エンドポイントは1リクエストで100件の ID またはリンクを受け付け、各ツイートを投稿者のプロフィール全体付きで返します。料金は1,000 ID あたり$0.014からなので、100万件が$14からで、毎秒20リクエストなら約8分で終わります。必要なのは API キー1つで、X の開発者アカウントは不要です。100回分の無料リクエストで、最初の10,000 ID をカバーできます。

100万件のツイートをリハイドレートするといくらかかりますか

100万件のツイート ID のリハイドレートは、100 ID のリクエスト単位で課金する Sorsa API なら$14から、返した投稿1件につき$0.005を課金する公式 X API なら$5,000です。2026年11月22日からは、公式 X API は expansions で要求した投稿者プロフィール1件ごとに$0.010も課金します。その従量課金プランは、月300万投稿の読み取りで止まります。

Hydrator アプリは今も使えますか

使えません。DocNow の Hydrator は Twitter が取り消したアプリケーションキーに依存しており、GitHub ページには、アプリはもう役に立たないと書かれています。twarc は今でもリハイドレートできますが、投稿ごとに課金される有料の公式 X API トークンが必要です。開発者アカウントなしで今データセットをリハイドレートするには、ID を100件ずつ Sorsa API の POST /tweet-info-bulk に送ってください。100万件あたり$14からです。

リハイドレートしたツイートを共有できますか

共有するのは ID で、ツイートではありません。X の開発者ポリシーは、他者と共有するデータセットに含めてよいのは投稿 ID とユーザー ID だけとしており、X が書面で同意しない限り、1人の受け手に30日あたり最大150万件の投稿 ID までです。リハイドレートした本文は自分の分析にとどめ、他の人が同じ作業を再現できるよう、ID リスト、リハイドレートした日付、回収率を公開してください。

コードを書かずにツイート ID をリハイドレートできますか

小さなリストなら可能です。Sorsa API のノーコードのプレイグラウンドは、自分のキーで POST /tweet-info-bulk を一度に最大100件の ID またはリンクについて実行し、ツイートを CSV、Excel、JSON にエクスポートします。数千から数百万件の ID なら、短いスクリプトのほうが速く、このガイドのスクリプトは無人で動き、クラッシュ後も再開できます。

#検証の方法

2026年11月2日に、docs.x.com の X の従量課金の料金表、Get Posts by IDs のリファレンス、レート制限の表、2026年10月23日付の expansions のお知らせ、開発者ポリシーを読み、POST /tweet-info-bulk のリクエストとレスポンスを Sorsa API の公開中の API リファレンスと照合しました。上のレスポンスは、デモアカウントを使った、ドキュメントどおりの形の短縮版の例です。あわせて、Hydrator と twarc の現在の README と、現在 Google、Bing、Brave で上位に表示されるリハイドレートのガイドも読みました。

Sorsa APIチーム 読み取り専用のX(Twitter)APIとスクレイピングツール、Sorsa APIを開発・運営しています。2022年から本番稼働し(旧TweetScout API)、累計60億リクエスト以上を処理しています。 Sorsa APIについて

変更点
  • 初公開。