X 검색 연산자가 통하는 무료 트위터 검색 API, 결과는 JSON으로

X 검색 연산자가 통하는 무료 트위터 검색 API, 결과는 JSON으로
Unif Cookbooks team
Unif Cookbooks team

업데이트

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:, 그리고 따옴표로 묶은 구문입니다. 결과는 페이지당 20건, 최신순이며, 다음 페이지로 넘어갈 nextCursor가 함께 옵니다. 무료 제한은 방문자당 10분에 20유닛이고 X-RateLimit-* 헤더에 표시되며, 검색은 업스트림에서 가장 비싼 호출이므로 2유닛을 쓰고, 따라서 검색으로는 10회입니다. 날짜를 넣지 않으면 최신 게시물을 받고, since:와 until:을 추가하면 같은 검색이 2006년까지 거슬러 올라갑니다.

계정 없이 X에서 하고 싶은 일 가운데, 검색은 괜찮은 무료 답이 없는 유일한 영역입니다. 링크 미리보기 API(FxTwitter, vxTwitter)는 단일 게시물을 읽습니다. syndication 엔드포인트도 단일 게시물을 읽습니다. 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:mediafrom:nasa filter:media사진이나 동영상이 있는 게시물만
filter:linksfilter:links링크가 있는 게시물만
-filter:replies#Formula1 -filter:replies답글 제외
-filter:retweetsfrom:nasa -filter:retweets리포스트 제외
lang:lang:ja언어 코드
ORnasa OR esa둘 중 하나

조합할 수 있습니다. "지난 일주일 동안 NASA가 올린, 좋아요 100개 이상에 사진이 있고 답글이 아닌 게시물"은 이렇게 씁니다.

from:nasa since:2026-09-30 min_faves:100 filter:media -filter:replies

트위터 고급 검색 페이지에는 가장 흔히 쓰는 다섯 가지(계정, 날짜, 좋아요, 미디어, 답글)마다 필터가 있고, 필터가 만든 질의를 표시합니다. 그 문자열이 API가 받는 것과 같습니다.

Top이 아니라 Recent

X 검색에는 두 가지 정렬이 있습니다. 관련성과 시간을 섞어서 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는 정확히 nextCursor가 설정되어 있을 때만 true입니다. 검색 한 페이지는 게시물 20건이므로, 요청 세 번으로 약 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가 검색에 대해 그 값을 노출하지 않습니다.
  • 보장. 무료 티어는 방문자별 상한이 있는 공유 인프라입니다. 물량이나 SLA가 필요한 워크플로는 필드 이름이 같은 종량제 API로 옮겨 갑니다.

스무 줄짜리 모니터링 루프

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분에 검색 한 번은 무료 20유닛 중 2유닛입니다. 이 루프는 제한에 걸리지 않지만, 그래도 429가 오는 경우를 처리합니다.

FAQ

2026년에 무료 트위터 검색 API가 있나요?

네, 바로 이것입니다. 로그인 없이, API 키 없이 무료로 쓸 수 있고, 방문자별 횟수 제한으로 10분에 검색 10회까지 가능합니다. 공식 X API에는 무료 검색 티어가 없습니다. 무료 플랜은 게시만 허용합니다.

트위터 고급 검색 연산자가 작동하나요?

네. 질의가 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과 함께 나열합니다.