| name | x-api |
| description | 트윗 및 스레드 게시, 타임라인 읽기, 검색 및 분석을 위한 X/Twitter API 통합. OAuth 인증 패턴, 속도 제한 및 플랫폼 네이티브 콘텐츠 게시를 다룹니다. 프로그래밍 방식으로 X와 상호작용하고자 할 때 사용하세요. |
| origin | ECC |
X API
게시, 읽기, 검색 및 분석을 위한 X(Twitter)와의 프로그래밍 방식 상호작용.
활성화 시점
- 프로그래밍 방식으로 트윗이나 스레드를 게시하고자 할 때
- X에서 타임라인, 멘션 또는 사용자 데이터를 읽을 때
- 콘텐츠, 트렌드 또는 대화를 위해 X를 검색할 때
- X 통합 서비스나 봇을 구축할 때
- 분석 및 참여도 추적 시
- 사용자가 "X에 게시해 줘", "트윗해 줘", "X API" 또는 "Twitter API"라고 말할 때
인증 (Authentication)
OAuth 2.0 Bearer Token (App-Only)
용도: 읽기 중심 작업, 검색, 공개 데이터 조회.
export X_BEARER_TOKEN="your-bearer-token"
import os
import requests
bearer = os.environ["X_BEARER_TOKEN"]
headers = {"Authorization": f"Bearer {bearer}"}
resp = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=headers,
params={"query": "claude code", "max_results": 10}
)
tweets = resp.json()
OAuth 1.0a (User Context)
용도: 트윗 게시, 계정 관리, DM 및 모든 쓰기 플로우 (필수).
export X_CONSUMER_KEY="your-consumer-key"
export X_CONSUMER_SECRET="your-consumer-secret"
export X_ACCESS_TOKEN="your-access-token"
export X_ACCESS_TOKEN_SECRET="your-access-token-secret"
오래된 설정에는 X_API_KEY, X_API_SECRET, X_ACCESS_SECRET과 같은 레거시 별칭이 존재할 수 있습니다. 새로운 플로우를 문서화하거나 연결할 때는 X_CONSUMER_* 및 X_ACCESS_TOKEN_SECRET 이름을 사용하는 것이 좋습니다.
import os
from requests_oauthlib import OAuth1Session
oauth = OAuth1Session(
os.environ["X_CONSUMER_KEY"],
client_secret=os.environ["X_CONSUMER_SECRET"],
resource_owner_key=os.environ["X_ACCESS_TOKEN"],
resource_owner_secret=os.environ["X_ACCESS_TOKEN_SECRET"],
)
핵심 작업
트윗 게시
resp = oauth.post(
"https://api.x.com/2/tweets",
json={"text": "Hello from Claude Code"}
)
resp.raise_for_status()
tweet_id = resp.json()["data"]["id"]
스레드 게시
def post_thread(oauth, tweets: list[str]) -> list[str]:
ids = []
reply_to = None
for text in tweets:
payload = {"text": text}
if reply_to:
payload["reply"] = {"in_reply_to_tweet_id": reply_to}
resp = oauth.post("https://api.x.com/2/tweets", json=payload)
tweet_id = resp.json()["data"]["id"]
ids.append(tweet_id)
reply_to = tweet_id
return ids
사용자 타임라인 읽기
resp = requests.get(
f"https://api.x.com/2/users/{user_id}/tweets",
headers=headers,
params={
"max_results": 10,
"tweet.fields": "created_at,public_metrics",
}
)
트윗 검색
resp = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=headers,
params={
"query": "from:affaanmustafa -is:retweet",
"max_results": 10,
"tweet.fields": "public_metrics,created_at",
}
)
목소리 모델링을 위한 최근 원본 게시물 추출
resp = requests.get(
"https://api.x.com/2/tweets/search/recent",
headers=headers,
params={
"query": "from:affaanmustafa -is:retweet -is:reply",
"max_results": 25,
"tweet.fields": "created_at,public_metrics",
}
)
voice_samples = resp.json()
사용자 이름으로 사용자 정보 가져오기
resp = requests.get(
"https://api.x.com/2/users/by/username/affaanmustafa",
headers=headers,
params={"user.fields": "public_metrics,description,created_at"}
)
미디어 업로드 및 게시
media_resp = oauth.post(
"https://upload.twitter.com/1.1/media/upload.json",
files={"media": open("image.png", "rb")}
)
media_id = media_resp.json()["media_id_string"]
resp = oauth.post(
"https://api.x.com/2/tweets",
json={"text": "Check this out", "media": {"media_ids": [media_id]}}
)
속도 제한 (Rate Limits)
X API 속도 제한은 엔드포인트, 인증 방식, 계정 등급에 따라 다르며 시간에 따라 변합니다. 항상 다음 사항을 준수하세요:
- 코드에 하드코딩된 가정을 넣기 전에 최신 X 개발자 문서를 확인하세요.
- 런타임에
x-rate-limit-remaining 및 x-rate-limit-reset 헤더를 읽으세요.
- 코드 내의 고정된 테이블에 의존하는 대신 자동으로 대기(back off)하세요.
import time
remaining = int(resp.headers.get("x-rate-limit-remaining", 0))
if remaining < 5:
reset = int(resp.headers.get("x-rate-limit-reset", 0))
wait = max(0, reset - int(time.time()))
print(f"Rate limit approaching. Resets in {wait}s")
에러 처리
resp = oauth.post("https://api.x.com/2/tweets", json={"text": content})
if resp.status_code == 201:
return resp.json()["data"]["id"]
elif resp.status_code == 429:
reset = int(resp.headers["x-rate-limit-reset"])
raise Exception(f"Rate limited. Resets at {reset}")
elif resp.status_code == 403:
raise Exception(f"Forbidden: {resp.json().get('detail', 'check permissions')}")
else:
raise Exception(f"X API error {resp.status_code}: {resp.text}")
보안 (Security)
- 토큰을 절대 하드코딩하지 마세요. 환경 변수나
.env 파일을 사용하세요.
.env 파일을 절대 커밋하지 마세요. .gitignore에 추가하세요.
- 토큰이 노출된 경우 즉시 교체(rotate)하세요. developer.x.com에서 재생성하세요.
- 쓰기 권한이 필요 없는 경우 읽기 전용 토큰을 사용하세요.
- OAuth 시크릿을 안전하게 저장하세요. 소스 코드나 로그에 남기지 마세요.
콘텐츠 엔진과의 통합
brand-voice와 content-engine을 사용하여 플랫폼 네이티브 콘텐츠를 생성한 후 X API를 통해 게시하세요:
- 목소리 매칭이 중요한 경우 최근 원본 게시물을 추출합니다.
VOICE PROFILE을 구축하거나 재사용합니다.
content-engine을 사용하여 X 네이티브 형식으로 콘텐츠를 생성합니다.
- 길이와 스레드 구조를 검증합니다.
- 사용자가 지금 게시하라고 명시적으로 요청하지 않는 한 승인을 위해 초안을 반환합니다.
- 승인된 후에만 X API를 통해 게시합니다.
public_metrics를 통해 참여도를 추적합니다.
관련 스킬
brand-voice: 실제 X 및 사이트/소스 자료를 바탕으로 재사용 가능한 목소리 프로필 구축
content-engine: X를 위한 플랫폼 네이티브 콘텐츠 생성
crosspost: X, LinkedIn 및 기타 플랫폼에 콘텐츠 배포
connections-optimizer: 네트워크 기반 아웃리치 초안 작성 전 X 그래프 재구성