X の検索演算子が使える、JSON を返す無料の Twitter 検索 API

更新日
API キーなしで、スクリプトや AI エージェントから最近の公開 X 投稿を JSON で検索: エンドポイント、使える演算子、カーソルページング、制限。
要点:
GET https://unifapi.com/tools/x/search?q=<query>は、クエリに一致する公開 X 投稿を JSON で返します。無料で使え、ログインもアカウントも API キーも不要で、訪問者ごとのレート制限があります。qでは X の検索演算子が使えます。from:、to:、since:、until:、min_faves:、min_retweets:、filter:media、filter:links、-filter:replies、lang:、そして引用符で囲んだフレーズです。結果は 1 ページ 20 件、新しい順で、ページングにはnextCursorを使います。無料の上限は訪問者ごとに 10 分あたり 20 ユニットでX-RateLimit-*ヘッダーに表示され、検索は上流で最も高価な呼び出しなので 2 ユニットを消費します。つまり検索なら 10 回分です。日付を指定しなければ最新の投稿が返り、since:とuntil:を加えれば、同じ検索で 2006 年までさかのぼれます。
アカウントなしで X に求めるもののうち、検索は無料の良い答えがないものでした。リンクプレビュー API(FxTwitter、vxTwitter)は投稿 1 件を読みます。syndication エンドポイントも投稿 1 件です。Nitter には検索がありましたが、公開 Nitter インスタンスの多くは消えたか法的にブロックされています。残るのは、有料枠付きの開発者アカウントか、x.com/search をヘッドレスブラウザで操作する方法で、後者は遅く、壊れやすく、規約にも反します。
この記事では、無料の検索エンドポイントが何をするか、どうクエリするか、どこで止まるかを説明します。
リクエスト
curl -s "https://unifapi.com/tools/x/search?q=from%3Anasa%20filter%3Amedia"
{
"query": "from:nasa filter:media",
"posts": {
"items": [
{
"id": "2107566197579341846",
"text": "After delivering science and supplies to the @Space_Station earlier this year, Northrop Grumman's Cygnus XL cargo spacecraft is scheduled to depart on Friday…",
"createdAt": "2026-10-06T20:18:32.000Z",
"url": "https://x.com/NASA/status/2107566197579341846",
"author": { "handle": "NASA", "name": "NASA", "verified": true, "followers": 92373839 },
"metrics": {
"likes": 2195,
"reposts": 302,
"replies": 114,
"quotes": 20,
"bookmarks": 104,
"views": 1520159
},
"media": [
{
"kind": "photo",
"url": "https://pbs.twimg.com/media/…jpg",
"width": 1920,
"height": 1280
}
]
}
],
"hasMore": true,
"nextCursor": "DAACCgACHUAq4qFAJxAKAAMd…"
}
}
人向けのページで同じリクエストをすると https://unifapi.com/tools/x-search?q=from:nasa filter:media になり、そのページ URL に &format=json を付けると上の JSON が返ります。代わりに format=md を付けるか Accept: text/markdown を送れば、投稿を Markdown で受け取れます。JSON よりモデルのコンテキストウィンドウに収まりやすい形式です。
使える演算子
クエリは書いたとおり X の検索に渡されるので、X が自身の検索ボックス向けにドキュメント化している演算子がここでも使えます。私たちがよく使うのは次のものです。
| 演算子 | 例 | 動作 |
|---|---|---|
from: | from:nasa | 特定アカウントの投稿 |
to: | to:nasa | あるアカウント宛ての返信 |
@handle | @nasa | あるアカウントに言及した投稿 |
#tag | #Formula1 | ハッシュタグ付きの投稿 |
"phrase" | "crew-12" | 完全一致のフレーズ |
since: / until: | since:2026-10-01 | 日付の範囲(日単位) |
min_faves: | min_faves:100 | いいねが N 件以上 |
min_retweets: | min_retweets:50 | リポストが N 件以上 |
filter:media | from:nasa filter:media | 写真または動画付きの投稿のみ |
filter:links | filter:links | リンク付きの投稿のみ |
-filter:replies | #Formula1 -filter:replies | 返信を除外 |
-filter:retweets | from:nasa -filter:retweets | リポストを除外 |
lang: | lang:ja | 言語コード |
OR | nasa OR esa | いずれかの語 |
組み合わせもできます。「NASA の直近 1 週間の投稿のうち、いいねが 100 件以上で写真付き、返信を除く」は次のとおりです。
from:nasa since:2026-09-30 min_faves:100 filter:media -filter:replies
Twitter 高度な検索のページには、特によく使う 5 つ(アカウント、日付、いいね、メディア、返信)それぞれのフィルターがあり、フィルターが組み立てたクエリが表示されます。API が受け取るのは、それと同じ文字列です。
Top ではなく Latest
X の検索には 2 つのランキングがあります。関連度と新しさを混ぜ、2009 年の投稿を平気で先頭に出す「Top(話題)」と、厳密に新しい順の「Latest(最新)」です。無料エンドポイントは Latest を要求します。監視、イベントへの反応、since: で範囲を指定するものなら、欲しいのはこちらです。「今週 X で最もいいねされた投稿」が欲しいなら、Latest の結果を metrics.likes で自分でソートするか、min_faves: を付けて末尾を切り落としてください。
ページング
無料 API のリストはすべて { items, hasMore, nextCursor } です。続きを読むには、カーソルをそのまま渡します。
curl -s "https://unifapi.com/tools/x/search?q=%23Formula1&cursor=DAACCgACHUAq4qFAJxAKAAMd…"
カーソルは不透明な文字列なので、パースしないでください。hasMore が true になるのは nextCursor がセットされているときだけです。検索ページは 20 件なので、3 回のリクエストで約 60 件を読め、20 ユニットのうち 6 を消費します。
上限はレスポンスの中に
HTTP/2 200
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 16
X-RateLimit-Reset: 1791357984
無料枠は、すべての /tools/x/* エンドポイントの合算で訪問者ごとに 10 分あたり 20 ユニット、検索は 2 ユニットです。使い切ると、Retry-After 付きの 429 と、上限を引き上げる場所を示す JSON 本文が返ります。
{
"error": {
"type": "rate_limited",
"message": "Free limit of 20 requests per 10 minutes reached. Retry after 412s, or use a UnifAPI workspace key (pay as you go) for uncapped access.",
"retryAfterSeconds": 412,
"upgrade": "https://unifapi.com/apis/twitter"
}
}
行儀のよいエージェントは、ページングするか決める前に X-RateLimit-Remaining を読み、ループで再試行する代わりに Retry-After の分だけ待ちます。
できないこと
- 関連度順。 結果は新しい順のみです。古い投稿にも日付で到達できます(
from:jack until:2006-04-01は 2006 年 3 月の投稿を返します)が、期間内のベストを先頭に並べる仕組みはありません。また、X はsince:/until:の日の境界を X 自身のタイムゾーンで区切るので、範囲が前後に数時間はみ出すことがあります。 - 保護されたアカウント。 返るのは公開投稿だけです。
- 件数。 「何件一致したか」の数値はありません。X は検索についてそれを公開していません。
- 保証。 無料枠は共有インフラで、訪問者ごとの上限があります。量や SLA が必要なワークフローは従量課金 API へ移行し、そこでもフィールド名は同じです。
20 行の監視ループ
import requests, time
BASE = "https://unifapi.com/tools/x/search"
seen = set()
def poll(query):
r = requests.get(BASE, params={"q": query}, headers={"Accept": "application/json"})
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", "60")))
return []
r.raise_for_status()
fresh = [p for p in r.json()["posts"]["items"] if p["id"] not in seen]
seen.update(p["id"] for p in fresh)
return fresh
while True:
for post in poll('"unifapi" -filter:replies'):
print(post["createdAt"], post["author"]["handle"], post["metrics"]["likes"], post["url"])
time.sleep(600)
10 分ごとの検索 1 回は無料の 20 ユニットのうち 2 ユニットです。このループが上限に触れることはなく、それでも 429 のケースを処理します。
FAQ
2026 年に無料の Twitter 検索 API はありますか?
はい、これです。無料で使え、ログインも API キーも不要で、訪問者ごとのレート制限により 10 分あたり検索 10 回までです。公式 X API には無料の検索枠がなく、無料プランで許されるのは投稿のみです。
Twitter の高度な検索演算子は使えますか?
はい。クエリは変更なしに X の検索へ渡されるので、from:、since:、until:、min_faves:、filter:media、-filter:replies、lang:、引用符で囲んだフレーズはすべて使えます。
検索はどこまで遡れますか?
2006 年までさかのぼれます。日付を指定しなければ最新の投稿から順に返り、since: と until: を加えるとその期間へ移動できます。たとえば from:jack until:2006-04-01 です。
結果を JSON ではなく Markdown で取得できますか?
はい。format=md を付けるか Accept: text/markdown を送ってください。Markdown では、各投稿が著者、テキスト、指標、URL とともに一覧になります。