本文へスキップ

Twitter検索APIでツイートを検索する方法

APIでツイートを検索するには、キーワードとXの検索演算子を組み合わせたクエリを検索エンドポイントに送り、一致したツイートをJSONのページで受け取ります。公式X APIの料金は、結果1,000件あたり$5.00です。

要点: X自身の検索は2つのエンドポイントに分かれています。直近検索は過去7日間を、全アーカイブ検索は2006年3月までをカバーし、どちらも開発者アカウントとBearerトークンが必要です。キー1つで検索するなら、Sorsa APIの POST /search-tweets が使えます。1リクエストで約20ツイート、2006年までさかのぼれて、1,000件あたり$0.07からです。まずは100回分の無料リクエストで試せます。

エンドポイント
POST /search-tweets
1ページの件数
1リクエストあたり約20ツイート
料金
1,000件あたり$0.07から

#Twitter検索APIの仕組み

Twitter検索APIとは、公開ツイートに対するXの検索を、あなたに代わって実行するエンドポイントです。"vector database" lang:en min_faves:20 のようなクエリを1つ送ると、一致したツイートのページが返ります。各ツイートには、本文、日付、各種カウント、投稿者が含まれ、次のページを取得するカーソルも付きます。

コードを書く前にクエリを試すなら、無料のTwitter高度な検索ツールで実行できます。最初の20件の一致投稿が表示され、設定したフィルターはすべて演算子としてクエリに書き込まれるので、そのままリクエストに貼り付けられます。

クエリ "vector database" lang:en min_faves:20 since:2026-10-01 POST /search-tweets ApiKey: YOUR_API_KEY JSONボディ: query, order, next_cursor ページ1 約20ツイート ツイート、数値、投稿者 ツイート、数値、投稿者 next_cursor ページ2 さらに約20件 以降も同様 カーソルなし: 検索完了
クエリを1つ送ると、約20ツイートずつのページが返ります。結果が尽きるまで、各ページに次のページへのカーソルが付きます。

返ってくる内容は、3つの設定で決まります。クエリは、語句、アカウント、言語、メディア、エンゲージメントでツイートを選びます。並び順は、エンゲージメントの高い一致から並べるTop(人気順)か、新しい順に並べるLatest(最新順)です。期間の指定は、Xのウェブ構文ではクエリ内の since: と until: に書き、公式X APIでは別の時間パラメーターに書きます。

公式X APIは、検索を2つのエンドポイントに分けています(Xの検索ドキュメント(新しいタブで開きます))。GET /2/tweets/search/recent は過去7日間をカバーし、1リクエストで10〜100件の投稿を返します。GET /2/tweets/search/all は2006年3月までさかのぼり、最大500件を返します。どちらも、承認された開発者アカウント、ProjectとApp、Bearerトークンが必要で、返した投稿1件ごとに$0.005が課金されます。

#Sorsa APIで4ステップでツイートを検索する

コードからツイートを検索するなら、Twitter(X)API兼スクレイピングツールであるSorsa APIが使えます。結果は1,000件あたり$0.07から、2006年までの任意の日付を指定でき、全プラン毎秒20リクエストです。開発者アカウントとOAuthの代わりに、必要なのは ApiKey ヘッダー1つです。x.comの検索ボックスと同じクエリ構文を読み取り、あなたのXアカウントには一切触れません。

  1. キーを取得します。 登録して、ダッシュボードからAPIキーをコピーします。100回分の無料リクエストは、すでに付いています。

  2. クエリを書きます。 x.comで入力するのと同じように書きます。語句、"exact phrases"、from:、lang:、min_faves:、since: が使えます。

  3. リクエストを送ります。 クエリをJSONボディに入れてPOST /search-tweets(新しいタブで開きます)にPOSTします。新しいツイートから順に取得するなら "order": "latest"、Topなら "popular" を指定します。

    Terminal
    curl -X POST "https://api.sorsa.io/v3/search-tweets" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "\"vector database\" lang:en min_faves:20", "order": "latest"}'
    
    Response200 OK
    {
      "tweets": [
        {
          "id": "2116173807613027825",
          "full_text": "Benchmarked three vector databases on 40M embeddings.",
          "created_at": "2026-10-30T14:22:07Z",
          "lang": "en",
          "likes_count": 214,
          "retweet_count": 37,
          "reply_count": 19,
          "quote_count": 6,
          "view_count": 18450,
          "bookmark_count": 92,
          "is_reply": false,
          "is_quote_status": false,
          "conversation_id_str": "2116173807613027825",
          "entities": [],
          "user": {
            "id": "1620350095193014349",
            "username": "indexlab_notes_daily",
            "display_name": "Index Lab Notes",
            "followers_count": 8312,
            "verified": false,
            "created_at": "2023-01-31T09:15:42Z"
          }
        }
      ],
      "next_cursor": "DAADDAABCgABHV3t2nWAJ8kKAAIdXcTm0Zvw"
    }
    
  4. カーソルをたどります。 どのツイートにも投稿者のプロフィール全体が含まれるので、別途問い合わせる必要はありません。次のページは、同じボディに next_cursor を入れて送り返します。カーソルのないレスポンスが返ったら止めてください。

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

下の欄に自分のクエリを貼り付けると、チェックしたうえで、curl、Python、Node.jsのリクエストを生成します。JSONボディ内の引用符はエスケープ済みです。このチェッカーは、ウェブ構文では使わない公式X APIの演算子名も指摘します。

並び順
例

問題は見つかりません。このクエリはXのWeb検索の構文で書かれており、 POST /search-tweets はそのまま受け付けます。

curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "\"vector database\" lang:en min_faves:20", "order": "latest"}'

1リクエストで約20ツイートが返るため、1,000件の結果には約50リクエストが必要です。Sorsa APIなら最安$0.07、公式X APIでは$5.00です。

クエリをチェックして、リクエストに変換しました。実行する前に、YOUR_API_KEYを自分のキーに置き換えてください。

#コードで動くクエリの書き方

/search-tweets のクエリは、x.comの検索ボックスに入力するのと同じ文字列です。そのため、ブラウザーで組み立てたものを、そのままリクエストに貼り付けられます。開発者がつまずく問題のほとんどは、7つのルールでカバーできます。

  • スペースはAND、OR は大文字、先頭の - は語句や演算子の除外、丸括弧はグループ化を表します。例:(rust OR golang) -hiring
  • 完全一致のフレーズは二重引用符で囲みます。生のJSON文字列の中では、引用符にバックスラッシュが必要です("\"vector database\"")。PythonとNode.jsでは、辞書やオブジェクトを渡せばライブラリがエスケープしてくれます。
  • ハッシュタグ、キャッシュタグ、メンションは書いたとおりに入れます。#buildinpublic、$NVDA、@acme_cloud_status です。クエリはJSONボディで送るので、URLエンコードは不要です。
  • 日付はクエリに書きます。since:2026-10-01 はその日を含み、until:2026-11-01 はその日の手前までで、どちらもUTCです。
  • エンゲージメントの下限は min_faves:、min_retweets:、min_replies: です。頭にマイナスを付けると下限が上限に変わります(-min_faves:1000)。
  • ネイティブのリツイートは、include:nativeretweets を付けない限り除外されます。-filter:replies を付けると、リプライ以外のトップレベルの投稿だけが残ります。
  • 1つのクエリに入る演算子は約22個までです。それより長いアカウントやキーワードのリストは、複数のクエリに分けてください。

チームがよく検索する内容のほとんどは、5つのパターンでカバーできます。どれも query フィールドにそのまま貼り付けられます。

クエリのパターン
# Mentions of a brand, without its own posts
("acme cloud" OR @acme_cloud_status) -from:acme_cloud_status

# The most liked posts on a topic
"vector database" min_faves:100 -filter:replies lang:en

# One account's posts on a subject in October
from:acme_cloud_status outage since:2026-10-01 until:2026-11-01

# Posts that link to a site
url:github.com rust -filter:replies

# Images under a hashtag
#buildinpublic filter:images

各演算子の癖と例は、Twitterの検索演算子の一覧にすべて載っています。

#全ページを取得して、検索を回し続ける

1ページより多く収集するには、直前のレスポンスの next_cursor を入れた同じボディをもう一度送り、カーソルのないレスポンスが返ったら止めます。1ページは約20ツイートで、件数にはばらつきがあります。ページが短くても検索の終わりを意味せず、終わりを示すのはカーソルがなくなったときだけです。

下のループは、届いたツイートを1件ずつJSON Linesファイルに書き込み、保存済みのIDは飛ばします。ページ数の上限を設けてあるので、広すぎるクエリでリクエストを使い込む心配はありません。

import json
import requests

API = "https://api.sorsa.io/v3/search-tweets"
HEADERS = {"ApiKey": "YOUR_API_KEY"}


def search(query, order="latest", max_pages=50):
    body = {"query": query, "order": order}
    for _ in range(max_pages):
        r = requests.post(API, json=body, headers=HEADERS, timeout=30)
        r.raise_for_status()
        page = r.json()
        yield from page.get("tweets", [])
        cursor = page.get("next_cursor")
        if not cursor:
            break
        body["next_cursor"] = cursor


seen = set()
with open("tweets.jsonl", "w", encoding="utf-8") as f:
    for t in search('"vector database" lang:en min_faves:20'):
        if t["id"] not in seen:
            seen.add(t["id"])
            f.write(json.dumps(t) + "\n")

検索を回し続けるには、同じループをタイマーで繰り返します。最新のツイートを取得し、前回保存した最大のIDを since_id: に指定して、カーソルが尽きるまで読み、新しい最大のIDを保存します。新しい投稿がなければ、確認にかかるのは1リクエストだけです。そのため、投稿の少ないクエリを頻繁に確認しても、費用は小さく済みます。

Python
import time

newest = None
while True:
    query = '"vector database" lang:en'
    if newest:
        query += f" since_id:{newest}"
    fresh = list(search(query))
    if fresh:
        newest = max(fresh, key=lambda t: int(t["id"]))["id"]
        print(len(fresh), "new tweets")
    time.sleep(300)

検索はポーリングで動きます。購読できるストリームはありません。アラート、スケジュール、Slackやメールへの通知まで含めたパイプライン全体は、Twitterのリアルタイム監視のガイドで構築します。リトライや並列検索は、PythonでTwitter APIのガイドで追加します。

知っておきたいこと

ツイートを収集したり数えたりするときは、必ず "order": "latest" を使ってください。一致するすべてのツイートを、新しいものから順にさかのぼります。Topタブに相当する "popular" は、エンゲージメントの高い一致だけを返すので、同じクエリでもTopを2回実行すると、異なる結果になることがあります。

#ハッシュタグでツイートを検索する

ハッシュタグで検索するには、タグを入力するときと同じ形で、#buildinpublic のようにクエリへ入れます。ハッシュタグとして書かれているツイートに、大文字小文字を問わず一致し、ほかのどの演算子とも組み合わせられます。

タグなしで同じ語句を書く人もいるなら、OR で通常の語句も加えます。(#buildinpublic OR "build in public") min_faves:10 -filter:replies lang:en のようにします。複数のタグは OR でつなぎます。株式や暗号資産のシンボルには、$NVDA のようなキャッシュタグを使います。

Sorsa APIでは、# がJSONボディにそのまま入ります。公式X APIのGETリクエストでは、%23 に変換する必要があります。エンコードしていない # はURLの終わりを意味するので、サーバーにはタグが届かないからです。ハッシュタグの推移を数えるには、since: と until: で1日ごとにLatestの検索を実行し、日ごとに返るツイートの数を数えます。

#目的の検索に合うエンドポイントを選ぶ

キーワード検索は、Sorsa APIでツイートを見つける5つの方法のうちの1つです。どのエンドポイントが適切かは、何を起点にするかで決まります。語句、1つのアカウント、アカウントの集合、あるいは人そのものです。

単語、フレーズ、演算子 POST /search-tweets 2006年まで遡る任意の日付の一致ツイート 1アカウントのハンドル POST /mentions メンションしたツイート(いいね数・日付で絞込可) 名前や自己紹介の語句 POST /search-users 一致するアカウントとそのプロフィール 1アカウント自身の投稿 POST /user-tweets タイムライン、新しい順 Xリストのアカウント群 GET /list-tweets メンバーのツイートを1つのフィードで
手元にあるものから始めます。クエリ、1つのアカウント、アカウントのリスト、探している人たちのどれかです。

残りの4つは、それぞれ別の起点から読み取ります。POST /mentions(新しいタブで開きます) は、ハンドルを1つ受け取り、そのアカウントにメンションしたツイートを返します。いいね、リプライ、リツイート、日付のフィルターをボディで指定できます。POST /search-users(新しいタブで開きます) は、名前や自己紹介が語句に一致するアカウントを探します。POST /user-tweets(新しいタブで開きます) は、1つのアカウント自身のタイムラインを1リクエストあたり約20ツイートで読み取ります。Xリストのメンバーの投稿は、GET /list-tweets(新しいタブで開きます) から1つのフィードとして返ります。そのため、最大5,000アカウントのリストを、1ページにつき1リクエストで監視できます。

ブランドのチームは、たいてい2つを組み合わせます。人々が製品について語る内容には /search-tweets、人々がそのアカウントに向けて語る内容には /mentions です。後者は、TwitterメンションAPIのガイドで解説しています。

#ツイート検索にかかる費用

Sorsa APIでは、検索結果は1,000ツイートあたり$0.07からです。1リクエストで約20ツイートが返り、中身にかかわらず1リクエストとして課金されます。公式X APIは、返した投稿1件ごとに$0.005、つまり1,000件あたり$5.00を課金します(Xの料金表(新しいタブで開きます))。

検索で収集するツイート

公式X API

$5,000

検索結果100万件の場合

1投稿$0.005

Sorsa API

$70から

検索結果100万件の場合

1,000件あたり$0.07から

71分の1のコスト

投稿者もあわせて取得すると、公式の料金は上がります。2026年11月22日から、Xはエクスパンション経由で返される各ユーザーに$0.010を課金します(Xの10月23日のお知らせ(新しいタブで開きます))。そのため、投稿者がすべて異なる結果1,000件は、$15.00になることがあります。Sorsa APIは、どのツイートにも投稿者のプロフィール全体を、追加料金なしで含めています。

量にも上限があります。従量課金は月間300万件の投稿読み取りで止まり、それを超える分は、XはEnterprise契約しか販売していません。Sorsa APIには300万件の上限がなく、プランは月間1,000万リクエストまで拡張できます。100回分の無料リクエストで約2,000件の検索結果を、カードなしで取得できます。公式の料金は、X APIの料金の解説にすべて載っています。

#公式X APIの検索との比較

公式X APIの検索は、結果1,000件あたりでSorsa APIの約71倍の費用がかかります。直近検索は過去7日間しか見られず、アプリあたり15分に450リクエストまでです。下の表で3つの検索エンドポイントを並べて比較します。公式の制限はXのレート制限表(新しいタブで開きます)によります。

Sorsa APIの /search-tweetsX 直近検索X 全アーカイブ検索
対象期間2006年3月まで過去7日間2006年3月まで
1リクエストの結果数約2010〜10010〜500
レート制限キーあたり毎秒20リクエストアプリあたり15分に450リクエスト毎秒1リクエスト、15分に300リクエスト
結果1,000件あたりの料金$0.07から$5.00$5.00
投稿者のプロフィールすべてのツイートに含まれる2026年11月22日から1人$0.010で課金2026年11月22日から1人$0.010で課金
クエリ構文x.comのウェブ検索v2演算子、512文字v2演算子、1,024文字
セットアップAPIキー1つ開発者アカウント、App、Bearerトークン開発者アカウント、App、Bearerトークン
  • 対象期間

    Sorsa APIの /search-tweets
    2006年3月まで
    X 直近検索
    過去7日間
    X 全アーカイブ検索
    2006年3月まで
  • 1リクエストの結果数

    Sorsa APIの /search-tweets
    約20
    X 直近検索
    10〜100
    X 全アーカイブ検索
    10〜500
  • レート制限

    Sorsa APIの /search-tweets
    キーあたり毎秒20リクエスト
    X 直近検索
    アプリあたり15分に450リクエスト
    X 全アーカイブ検索
    毎秒1リクエスト、15分に300リクエスト
  • 結果1,000件あたりの料金

    Sorsa APIの /search-tweets
    $0.07から
    X 直近検索
    $5.00
    X 全アーカイブ検索
    $5.00
  • 投稿者のプロフィール

    Sorsa APIの /search-tweets
    すべてのツイートに含まれる
    X 直近検索
    2026年11月22日から1人$0.010で課金
    X 全アーカイブ検索
    2026年11月22日から1人$0.010で課金
  • クエリ構文

    Sorsa APIの /search-tweets
    x.comのウェブ検索
    X 直近検索
    v2演算子、512文字
    X 全アーカイブ検索
    v2演算子、1,024文字
  • セットアップ

    Sorsa APIの /search-tweets
    APIキー1つ
    X 直近検索
    開発者アカウント、App、Bearerトークン
    X 全アーカイブ検索
    開発者アカウント、App、Bearerトークン

公式のエンドポイントは、デフォルトでは id と text しか返しません。日付、カウント、投稿者が返るのは、tweet.fields、expansions、user.fields で指定したときだけです。Sorsa APIでは、どのツイートもすべてのフィールドつきで届きます。

#ウェブ構文と公式X APIの演算子の違い

公式X APIは独自の演算子名を使うため、x.comの検索ボックスからコピーしたクエリが、そこでは失敗することがあります。min_faves: と min_retweets: は400エラーで拒否され、日付はクエリではなく start_time と end_time のパラメーターで渡します。Sorsa APIはウェブ構文を受け付けるので、左の列は書いたとおりに動きます。

やりたいことウェブ構文(x.com、Sorsa API)公式X API v2
いいね20以上min_faves:20min_likes:20
リポスト5以上min_retweets:5min_reposts:5
2026年10月のみsince:2026-10-01 until:2026-11-01start_time と end_time のパラメーター
リプライのみfilter:repliesis:reply
メディアやリンクつきの投稿filter:media、filter:linkshas:media、has:links
リツイートデフォルトで除外2026年5月4日からキーワード検索で除外
語句、アカウント、言語from:、to:、#、@、"phrase"、lang:同じ
  • いいね20以上

    ウェブ構文(x.com、Sorsa API)
    min_faves:20
    公式X API v2
    min_likes:20
  • リポスト5以上

    ウェブ構文(x.com、Sorsa API)
    min_retweets:5
    公式X API v2
    min_reposts:5
  • 2026年10月のみ

    ウェブ構文(x.com、Sorsa API)
    since:2026-10-01 until:2026-11-01
    公式X API v2
    start_time と end_time のパラメーター
  • リプライのみ

    ウェブ構文(x.com、Sorsa API)
    filter:replies
    公式X API v2
    is:reply
  • メディアやリンクつきの投稿

    ウェブ構文(x.com、Sorsa API)
    filter:media、filter:links
    公式X API v2
    has:media、has:links
  • リツイート

    ウェブ構文(x.com、Sorsa API)
    デフォルトで除外
    公式X API v2
    2026年5月4日からキーワード検索で除外
  • 語句、アカウント、言語

    ウェブ構文(x.com、Sorsa API)
    from:、to:、#、@、"phrase"、lang:
    公式X API v2
    同じ

2026年の2つの変更が、古いガイドの内容が食い違う理由です。Xは2026年1月19日に min_likes:、min_replies:、min_reposts: を停止し、5月4日に復活させました。このとき検索が新しいインデックスに移り、キーワードの結果からリツイートも除外されました(Xの変更履歴(新しいタブで開きます))。公式X APIはエンゲージメントのフィルターを無視する、と書いているページやAIの回答は、その間の数か月を説明しているものです。

統合ごと公式エンドポイントから移行するなら、公式X APIからの移行のガイドが、v2のすべてのパラメーターと演算子をSorsa APIに対応づけています。

#今日からツイート検索を始める

コードからのツイート検索は、クエリ1つとカーソル1つに集約されます。Sorsa APIなら、x.comで普段入力しているクエリを POST /search-tweets に送るだけで、2006年までの任意の日付から、投稿者つきで1リクエストあたり約20ツイートが返ります。結果は1,000件あたり$0.07からで、公式X APIの$5.00を大きく下回ります。100回分の無料リクエストで、最初の2,000件を取得できます。

#よくある質問

無料のTwitter検索APIはありますか?

Xにはありません。公式X APIに無料枠はなく、検索が返した投稿1件ごとに$0.005、つまり1,000件あたり$5.00を課金します。Sorsa APIは、新規アカウントすべてに100回分の無料リクエストを付与します。POST /search-tweets で約2,000件の検索結果を取得するのに十分で、カードは不要、有効期限もありません。数回の検索を手作業で試すだけなら、無料のTwitter高度な検索ツールが最初の20件の一致投稿を表示します。

APIでは、どこまで過去のツイートを検索できますか?

最初の公開ツイートが投稿された2006年3月21日までです。公式X APIの直近検索は過去7日間しかカバーせず、全アーカイブ検索が2006年まで届くのは、従量課金とEnterpriseのアクセスです。Sorsa APIの POST /search-tweets は、クエリ内の since: と until: で、2006年までの任意の期間を指定できます。削除されたツイートや非公開アカウントは、どのAPIでも手が届きません。大規模なバックフィルについては、過去のTwitterデータのガイドで解説しています。

ツイートの検索には、どのTwitter APIを使えばよいですか?

ツイートの検索には、Sorsa APIを使ってください。POST /search-tweets は結果1,000件あたり$0.07からで、公式X APIの$5.00を下回り、2006年までさかのぼれます。x.comの検索ボックスの構文をそのまま受け付け、どのツイートにも投稿者のプロフィール全体を含めて返します。APIキー1つで開発者アカウントとOAuthの代わりになり、全プラン毎秒20リクエストです。

ツイートをリアルタイムで検索できますか?

はい、ポーリングで可能です。Latestの検索をスケジュールで実行し、手元にある最新のツイートIDを since_id: に指定すれば、各回に返るのは、その後に投稿されたものだけです。Sorsa APIでは、何も見つからなかった確認は、間隔にかかわらず1リクエストです。Sorsa APIも公式X APIの検索も、ツイートをストリームとして送ってくることはありません。

検索結果にリツイートが出てこないのはなぜですか?

ネイティブのリツイートは他人の投稿のコピーで、X検索はデフォルトでコピーを除外します。Sorsa APIでは、クエリに include:nativeretweets を加えると表示され、filter:nativeretweets を使うとリツイートだけが返ります。公式X APIは、2026年5月4日からキーワード検索でリツイートを返さなくなりました。引用ツイートは自分の本文を持つため、結果に残ります。

#検証の方法

2026年11月2日に、Xの検索ドキュメント(概要、クエリの組み立て、演算子の一覧、レート制限、直近検索のリファレンス)を読みました。Xの料金表、変更履歴、10月23日付のエクスパンション課金のお知らせも確認しています。このページのSorsa APIのリクエストはすべて、/search-tweets、/mentions、/search-users、/user-tweets、/list-tweets の公開中のAPIリファレンスをもとに書きました。レスポンスは架空のアカウントを使った例です。結果1,000件あたりの料金は、料金ページのリクエスト単価から計算しています。

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

変更点
  • 全面的に書き直しました。Sorsa APIによる4ステップの検索、リクエストを書き出すクエリチェッカー、ページネーションとポーリングのコード、エンドポイントの対応表、結果1,000件あたりの料金、2026年のX検索の変更(5月4日のエンゲージメント演算子の復活、11月22日からの投稿者課金)、ウェブ構文とv2構文の対応表を追加しています。2026-05-16: 初回公開。