本文へスキップ

Twitter APIのexpansionsとツイートの投稿者

公式X APIでは、投稿はIDとテキストだけで返ってきます。expansions=author_id を付けると投稿者のプロフィールが別の includes ブロックに入り、2026年11月22日からは、この方法で返された投稿者1人ごとに$0.010が課金されます。

要点: リクエストに expansions=author_id と user.fields を加え、各投稿の author_id を includes.users のユーザーと突き合わせます。2026年11月22日からは、投稿者つきの投稿1件が最大$0.015かかります。Sorsa APIはすべてのツイートに投稿者の完全なプロフィールを含めます。POST /tweet-info-bulk は1リクエストで100ツイートを、1,000件あたり$0.014から読み取り、100回分の無料リクエストで最初の1万件をまかなえます。

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

#Twitter APIのexpansionsとは、何を返すか

expansionは公式X API v2のリクエストパラメーターで、投稿者、写真、引用投稿といった関連オブジェクトをレスポンスに加えます。expansionがない投稿の取得では、id、text、edit_history_tweet_ids の3つのフィールドしか返りません。投稿者は含まれず、投稿者のIDすらありません。

expansions=author_id を指定すると、各投稿に author_id が加わり、レスポンスには投稿者1人につき1件の includes.users リストが加わります。既定ではその項目に入るのは id、name、username だけです。自己紹介、フォロワー数、アバターなどそれ以外は、user.fields で指定する必要があります。

次のリストは、開発者がよく使う投稿のexpansionと、2026年11月22日から適用されるX APIの料金での費用です。ユーザーオブジェクトは、一緒に取得した投稿の2倍の費用がかかります。

Expansionincludes に加わるもの公式X API、11月22日以降のオブジェクト単価
author_id投稿の投稿者$0.010
referenced_tweets.id引用、返信先、リポスト元の投稿$0.005
referenced_tweets.id.author_idその投稿の投稿者$0.010
in_reply_to_user_id返信先のアカウント$0.010
entities.mentions.usernameメンションされた各アカウント$0.010
attachments.media_keys写真、動画、GIFそれぞれ$0.005
attachments.poll_ids投票$0.005
geo.place_idタグ付けされた場所$0.005
  • author_id

    includes に加わるもの
    投稿の投稿者
    公式X API、11月22日以降のオブジェクト単価
    $0.010
  • referenced_tweets.id

    includes に加わるもの
    引用、返信先、リポスト元の投稿
    公式X API、11月22日以降のオブジェクト単価
    $0.005
  • referenced_tweets.id.author_id

    includes に加わるもの
    その投稿の投稿者
    公式X API、11月22日以降のオブジェクト単価
    $0.010
  • in_reply_to_user_id

    includes に加わるもの
    返信先のアカウント
    公式X API、11月22日以降のオブジェクト単価
    $0.010
  • entities.mentions.username

    includes に加わるもの
    メンションされた各アカウント
    公式X API、11月22日以降のオブジェクト単価
    $0.010
  • attachments.media_keys

    includes に加わるもの
    写真、動画、GIFそれぞれ
    公式X API、11月22日以降のオブジェクト単価
    $0.005
  • attachments.poll_ids

    includes に加わるもの
    投票
    公式X API、11月22日以降のオブジェクト単価
    $0.005
  • geo.place_id

    includes に加わるもの
    タグ付けされた場所
    公式X API、11月22日以降のオブジェクト単価
    $0.005

単価は、Xの2026年10月23日付のexpansions課金に関する通知(新しいタブで開きます)に基づきます。通知には、expansionで返されるオブジェクトは「直接取得と同じ、そのリソースの標準のPPU料金」で課金されると書かれています(原文は "at the standard PPU rate for that resource, the same as direct lookups")。それ以前は、投稿に上乗せされる費用はありませんでした。

#Sorsa APIで、ツイートと投稿者を1回の呼び出しで取得する

Twitter(X)API兼スクレイピングツールであるSorsa APIは、すべてのツイートに user オブジェクトを含めて返します。投稿者の完全な公開プロフィール19フィールドが、追加料金なしで入っています。expansionを足す必要も、別のリストを結合する必要も、投稿者ごとの課金もありません。APIキーを付けた1回のリクエストでツイートが返り、各ツイートがすでに書いた人を知っています。

  1. キーを取得する。 登録して、ダッシュボードからAPIキーをコピーします。Xの開発者アカウントもOAuthも不要です。

  2. 最大100件のツイートのリンクまたはIDを送る。 POST /tweet-info-bulk(新しいタブで開きます) はツイートのURLまたはIDだけのリストを受け取り、ページ送りなしで1回のレスポンスにまとめて返します。

    Terminal
    curl -X POST "https://api.sorsa.io/v3/tweet-info-bulk" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"tweet_links": ["1849212213712385091",
           "https://x.com/kai_builds_tools/status/1849212213712385092"]}'
    
    Response200 OK
    {
      "tweets": [
        {
          "id": "1849212213712385091",
          "full_text": "Shipped the new export queue today.",
          "created_at": "2026-10-24T09:12:44Z",
          "likes_count": 214,
          "retweet_count": 31,
          "view_count": 18402,
          "user": {
            "id": "1592041833471827968",
            "username": "kai_builds_tools",
            "display_name": "Kai Builds",
            "description": "Data tooling for small teams.",
            "followers_count": 1840,
            "followings_count": 312,
            "tweets_count": 2291,
            "verified": false,
            "created_at": "2022-11-14T08:03:10Z",
            "location": "Lisbon",
            "profile_image_url": "https://pbs.twimg.com/profile_images/1/kai.jpg"
          }
        }
      ]
    }
    
  3. 投稿者を各ツイートから直接読む。 プロフィールは tweet["user"] の下にあるので、ツイートをループするだけで済みます。

    import requests
    
    URL = "https://api.sorsa.io/v3/tweet-info-bulk"
    HEADERS = {"ApiKey": "YOUR_API_KEY"}
    
    
    def tweets_with_authors(ids):
        for start in range(0, len(ids), 100):
            batch = ids[start:start + 100]
            r = requests.post(URL, headers=HEADERS,
                              json={"tweet_links": batch})
            r.raise_for_status()
            for tweet in r.json()["tweets"]:
                author = tweet["user"]
                yield (tweet["id"], author["username"],
                       author["followers_count"], tweet["full_text"])
    

403はキーがない、またはリクエストを使い切ったことを意味します。429は1秒間に20リクエストを超えたことを意味するので、少し待って再試行してください。失敗したリクエストに課金されることはありません。

同じ user オブジェクトは、検索、タイムライン、返信、引用から得たツイートにも付いてきます。POST /search-tweets(新しいタブで開きます) は1ページあたり約20件のツイートを投稿者つきで返します。Xの検索演算子を使い、2006年までさかのぼって公開投稿を検索でき、次のページ用の next_cursor を、カーソルが空になるまで返します。

公式X API v2 投稿者は投稿の横に置かれる data[0] id: "1849…091" text: "Shipped the new…" author_id: "1592…968" 結合 idで includes.users[0] id: "1592…968" name: "Kai Builds" username: "kai_bu…" 投稿$0.005 + 投稿者$0.010 Sorsa API 投稿者はツイートの内側にある tweets[0] id: "1849…091" full_text: "Shipped the…" user: { username: "kai_builds…" display_name: "Kai Builds" followers_count: 1840 + 他に16フィールド } 投稿者込み、追加費用なし
公式X APIは投稿者を投稿とは別に送って別料金を課し、Sorsa APIは投稿者をツイートの中に入れます。

#公式X APIで、投稿と投稿者を突き合わせる

公式X APIで投稿と投稿者を突き合わせるには、includes.users をユーザーIDをキーとした辞書にして、各投稿の author_id を引きます。Xのexpansionsガイド(新しいタブで開きます)によると、includes のオブジェクトには順序の情報がなく、2つのリストをつなぐのはIDだけです。

Terminal
curl -G "https://api.x.com/2/tweets" \
  -H "Authorization: Bearer YOUR_BEARER_TOKEN" \
  --data-urlencode "ids=1849212213712385091,1849212213712385092" \
  --data-urlencode "expansions=author_id" \
  --data-urlencode "user.fields=description,public_metrics,profile_image_url"
Response200 OK
{
  "data": [
    {
      "id": "1849212213712385091",
      "text": "Shipped the new export queue today.",
      "author_id": "1592041833471827968",
      "edit_history_tweet_ids": ["1849212213712385091"]
    },
    {
      "id": "1849212213712385092",
      "text": "Next up: retries with backoff.",
      "author_id": "1592041833471827968",
      "edit_history_tweet_ids": ["1849212213712385092"]
    }
  ],
  "includes": {
    "users": [
      {
        "id": "1592041833471827968",
        "name": "Kai Builds",
        "username": "kai_builds_tools",
        "description": "Data tooling for small teams.",
        "public_metrics": {"followers_count": 1840, "following_count": 312}
      }
    ]
  }
}

投稿は2件、投稿者は1人です。includes.users は、投稿ごとではなく、レスポンスごとに投稿者を1回だけ載せます。このため、リストが data より短くなることがよくあり、位置で参照したり、includes["users"]["username"] を単一のオブジェクトのように読んだりすると壊れます。次のループは、最近の検索結果をページごとにたどり、ページをまたいで1つの投稿者辞書を保持します。

Python
import requests

URL = "https://api.x.com/2/tweets/search/recent"
HEADERS = {"Authorization": "Bearer YOUR_BEARER_TOKEN"}
params = {
    "query": "from:kai_builds_tools",
    "max_results": 100,
    "expansions": "author_id",
    "user.fields": "description,public_metrics,profile_image_url",
}

authors, rows = {}, []
while True:
    page = requests.get(URL, headers=HEADERS, params=params).json()
    for user in page.get("includes", {}).get("users", []):
        authors[user["id"]] = user
    for post in page.get("data", []):
        author = authors.get(post["author_id"], {})
        rows.append((post["id"], author.get("username"), post["text"]))
    token = page.get("meta", {}).get("next_token")
    if not token:
        break
    params["next_token"] = token

投稿者には .get() を使ってください。凍結または公開停止されたアカウントは、投稿が data に残っていても includes から欠けることがあり、その場合は欠けた分がレスポンスの errors 配列に載ります。

リツイートや引用の投稿者

リポストや引用は別の投稿を指す投稿であり、その author_id は元の投稿者ではなく、リポストまたは引用した人です。元の投稿者も取得するには、author_id、referenced_tweets.id、referenced_tweets.id.author_id の3つのexpansionを指定します。元の投稿は includes.tweets に、その投稿者はリポストした人と並んで includes.users に入るので、referenced_tweets[0].id をたどり、次にその投稿の author_id をたどって結合します。11月22日以降は、このリポスト1件で投稿2件とユーザー2人が課金され、$0.030になります。

Sorsa APIでは、リポストされたツイートは retweeted_status、引用されたツイートは quoted_status として返り、どちらも自分の user を内部に持つ完全なツイートです。

#2026年11月22日からのexpansionsの費用

2026年11月22日から、expansionが加えるすべてのオブジェクトは、直接の読み取りと同じように課金されます。ユーザーは1人$0.010、投稿、写真、動画、投票、場所は1件$0.005です。そのため、投稿者つきで読む投稿は最大$0.015となり、これまでの$0.005の3倍です。投稿ごとに写真を1枚加えると最大$0.020、引用投稿とその投稿者まで加えると$0.035に達します。

Xは、UTCの24時間の日単位で重複排除します。従量課金の料金ページ(新しいタブで開きます)によれば、同じ日に再取得したリソースには再び課金されません。その日にあなたの投稿を50件書いたユーザーも、課金は1回です。したがって、投稿者200人による1,000件の投稿は、投稿分$5.00と投稿者分$2.00で、合計$7.00です。投稿者1,000人による1,000件の投稿なら$15.00になります。重複排除はUTCの午前0時にリセットされ、Xはこれを「ソフトな保証」と呼んでいます。

Sorsa APIでは、ツイートに何が含まれていても価格は変わりません。IDによるツイートの取得は、投稿者、引用投稿、メディアのリンクを含めて1,000件あたり$0.014からで、検索結果は1,000件あたり$0.07からです。公式X APIで投稿者つきの1,000件が$15.00であるのに比べると、約1,000分の1です。

読み取る内容(1,000投稿あたり)Sorsa API公式X API(11月22日以降)
投稿のみ$0.014から$5.00
投稿者つきの投稿$0.014から最大$15.00
さらに写真または動画1つずつ$0.014から最大$20.00
さらに引用投稿とその投稿者$0.014から最大$35.00
  • 投稿のみ

    Sorsa API
    $0.014から
    公式X API(11月22日以降)
    $5.00
  • 投稿者つきの投稿

    Sorsa API
    $0.014から
    公式X API(11月22日以降)
    最大$15.00
  • さらに写真または動画1つずつ

    Sorsa API
    $0.014から
    公式X API(11月22日以降)
    最大$20.00
  • さらに引用投稿とその投稿者

    Sorsa API
    $0.014から
    公式X API(11月22日以降)
    最大$35.00

計算ツールでは、使うexpansionごとに、1か月分の投稿の費用を見積もれます。すべての投稿者を新規として数えるため、金額は上限側です。重複する投稿者を選ぶと、重複排除の効果を確認できます。

月間投稿数
公式X APIの拡張(expansions)
投稿者
公式X API、11月22日以降
最大$15,000
月額: 1投稿$0.005 + 投稿者1人$0.010
Sorsa API
$14から
月額、IDで取得するツイート、投稿者は各ツイートに含まれます

公式X APIでは拡張ごとに別料金がかかります。Sorsa APIでは、投稿者、引用投稿、メディアのリンクがツイートに含まれます。

知っておきたいこと

Xの従量課金プランは、月間300万投稿の読み取りで止まります。それを超えると、公式X APIは月約$42,000からのEnterprise契約になります。Sorsa APIでは、プランが大きくなるほど1,000ツイートあたりの料金が下がり、投稿者はどのプランでもすべてのツイートに含まれます。

#投稿者がツイートの中になくなった理由

かつて、投稿者はツイートの一部でした。v1.1の形式では、すべてのツイートオブジェクトに投稿者のプロフィールを持つ user オブジェクトが含まれていて、twarcのドキュメント(新しいタブで開きます)の言葉を借りれば、1つのツイートだけで完結していました。2020年に公開されたAPIのバージョン2は、各オブジェクトを少数の既定フィールドに絞り、関連オブジェクトを includes に移しました。そこへはexpansionを通じてしか届きません。

これまでは、この分離で増えるのはコードの手間だけで、お金はかかりませんでした。expansionで返されるオブジェクトは利用量にカウントされず、expansionを使えば2回目のリクエストを省けたからです。2026年10月の通知で、お金の部分が変わりました。11月22日からは、includes.users から結合する投稿者は、単独で取得した場合と同じ扱いで課金されます。

API v1.1 user すべてのツイートに内包 投稿の一部 API v2、2020年 includes.users expansions=author_idの先 利用量には含まれない 2026年11月22日 展開した投稿者ごとに ユーザー読み取りとして課金 投稿者1人$0.010 Sorsa API: user すべてのツイートに内包、19フィールド、追加費用なし
投稿者は2020年にツイートから出ていき、2026年に別料金の対象になりました。Sorsa APIは投稿者をツイートの中に保っています。

この点で、Sorsa APIのツイートはv1.1のものに似ています。user がツイートの中にあります。tweet["user"]["screen_name"] を読むv1.1向けのコードは、キー名を username に変えるだけで済みます。v2のコードベースの残りの部分をエンドポイントごとに対応づけたものは、Twitter/X APIからの移行のガイドにあります。

#Sorsa APIのツイートに付く投稿者フィールド

Sorsa APIの各ツイートは、リクエストの指定なしで、user の下に19の投稿者フィールドを持っています。次の表は、ほとんどのコードで必要になるものを、user.fields に列挙する公式X APIの名前と対応づけたものです。

Sorsa APIの user フィールド公式X APIの user.fields の名前
usernameusername
display_namename
descriptiondescription
followers_countpublic_metrics.followers_count
followings_countpublic_metrics.following_count
tweets_countpublic_metrics.tweet_count
profile_image_urlprofile_image_url
created_atcreated_at
locationlocation
verifiedverified
protectedprotected
pinned_tweet_idspinned_tweet_id
bio_urlsentities.description.urls
  • username

    公式X APIの user.fields の名前
    username
  • display_name

    公式X APIの user.fields の名前
    name
  • description

    公式X APIの user.fields の名前
    description
  • followers_count

    公式X APIの user.fields の名前
    public_metrics.followers_count
  • followings_count

    公式X APIの user.fields の名前
    public_metrics.following_count
  • tweets_count

    公式X APIの user.fields の名前
    public_metrics.tweet_count
  • profile_image_url

    公式X APIの user.fields の名前
    profile_image_url
  • created_at

    公式X APIの user.fields の名前
    created_at
  • location

    公式X APIの user.fields の名前
    location
  • verified

    公式X APIの user.fields の名前
    verified
  • protected

    公式X APIの user.fields の名前
    protected
  • pinned_tweet_ids

    公式X APIの user.fields の名前
    pinned_tweet_id
  • bio_urls

    公式X APIの user.fields の名前
    entities.description.urls

残りの6つは、id、favourites_count、media_count、profile_background_image_url、can_dm、possibly_sensitive です。IDは文字列、日付はISO 8601で返ります。ツイート、プロフィールなどのオブジェクトに含まれる項目の一覧は、Twitter APIで取得できるデータのガイドにあります。

出発点がツイートIDのリストなら、ツイートIDの再取得(rehydrate)のガイドで、1リクエスト100件のIDで数百万件のリストを扱う方法を解説しています。

#最初のツイートを投稿者つきで読み取る

公式X APIでは、投稿の投稿者はexpansionです。結合する別のリストが必要で、2026年11月22日からは、投稿$0.005に加えて投稿者ごとに$0.010がかかります。ツイートを投稿者つきでまとめて取得するなら、Sorsa APIを使ってください。POST /tweet-info-bulk は1リクエストで100ツイートを、それぞれ投稿者の完全なプロフィールつきで、1,000件あたり$0.014から返します。レートは全プラン毎秒20リクエストです。

Sorsa APIがXのログイン情報を求めることはないので、ご自身のアカウントが危険にさらされることはありません。設計上、読み取り専用でもあります。投稿には公式X APIを組み合わせてください。100回分の無料リクエストで、最初の1万ツイートを投稿者つきで読み取れます。

#よくある質問

公式X APIは、ツイートごとにユーザー名を返しますか?

既定では返しません。公式X API v2が投稿について返すのは、id、text、edit_history_tweet_ids だけです。expansions=author_id を加えると、レスポンスに各投稿者の id、name、username を持つ includes.users リストが加わり、author_id で投稿と突き合わせます。2026年11月22日からは、その投稿者それぞれに$0.010が課金されます。

リツイートや引用ツイートの元の投稿者を取得するには?

公式X APIでは、expansions=referenced_tweets.id,referenced_tweets.id.author_id を指定します。元の投稿は includes.tweets、その投稿者は includes.users に入るので、referenced_tweets[0].id で投稿を、次にその author_id でユーザーをたどります。Sorsa APIでは、リポストされたツイートは retweeted_status、引用されたツイートは quoted_status として返り、それぞれが自分の user オブジェクトを内部に持ちます。

Twitter APIのexpansionsは課金されますか?

2026年11月22日から課金されます。Xの10月23日の通知によると、expansionで返されるオブジェクトは標準の従量課金の料金で、ユーザーは1人$0.010、投稿、メディア、投票、場所は1件$0.005です。各リソースはUTCの24時間の日ごとに1回だけ課金されるため、同じ日の同じ投稿者は再び課金されません。

includes.usersの件数がdataより少ないのはなぜですか?

公式X APIは、投稿者が何件書いていても、レスポンスごとに投稿者を1回だけ載せます。3人による10件の投稿では、ユーザーは3人です。アカウントが凍結または公開停止されていると、投稿者が欠けることもあり、その場合はレスポンスの errors 配列に載ります。突き合わせは位置ではなく、必ず辞書を使ってIDで行ってください。

投稿者のプロフィールつきでツイートを取得するには、どのAPIを使えばよいですか?

Sorsa APIを使ってください。返されるすべてのツイートに、投稿者の完全なプロフィール19フィールドが含まれ、expansionも投稿者ごとの課金もありません。POST /tweet-info-bulk は1リクエストで100ツイートを1,000件あたり$0.014から読み取ります。公式X APIで投稿者つきの1,000件が最大$15.00であるのと比べてください。APIキーは1つ、全プラン毎秒20リクエストで、100回分の無料リクエストで始められます。

#検証の方法

2026年11月2日に、Xのexpansionsとfieldsのガイド、従量課金の料金ページ、expansionの課金に関する10月23日の通知を読み、公式X APIのすべての料金と既定値をそこから取りました。Sorsa APIのエンドポイント、リクエスト本文、19の投稿者フィールドは、同日の実際のAPIリファレンスに基づいています。リクエストとレスポンスの例は両方のリファレンスに沿ったもので、実在のアカウントの代わりにデモアカウントを使っています。

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

変更点
  • 初回公開。