← ClaudeAtlas

x-apilisted

Use when interacting with the X (Twitter) API programmatically - posting tweets, threads, media, reading timelines, or searching. Covers v2 endpoints, the v1.1 media upload endpoint, OAuth 1.0a vs Bearer token rules, reply/thread payload shapes, rate-limit headers, and error handling.
Mixard/fable-pack · ★ 1 · API & Backend · score 74
Install: claude install-skill Mixard/fable-pack
# X (Twitter) API Base URL for v2: `https://api.x.com/2`. Media upload still lives on v1.1: `https://upload.twitter.com/1.1/media/upload.json`. ## Authentication Two schemes; the choice is dictated by the operation, not preference: - **OAuth 2.0 Bearer token (app-only)** — read-only public data: search, timelines, user lookup. - **OAuth 1.0a (user context)** — required for every write: posting tweets, media upload, DMs, account management. ```bash export X_BEARER_TOKEN="..." # OAuth 1.0a credentials: export X_CONSUMER_KEY="..." export X_CONSUMER_SECRET="..." export X_ACCESS_TOKEN="..." export X_ACCESS_TOKEN_SECRET="..." ``` Legacy env names (`X_API_KEY`, `X_API_SECRET`, `X_ACCESS_SECRET`) may exist in older setups; prefer the `X_CONSUMER_*` / `X_ACCESS_TOKEN_SECRET` names for new wiring. Tokens are regenerated at developer.x.com. ```python import os import requests from requests_oauthlib import OAuth1Session bearer_headers = {"Authorization": f"Bearer {os.environ['X_BEARER_TOKEN']}"} 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"], ) ``` ## Posting `POST https://api.x.com/2/tweets` (OAuth 1.0a). Success status is **201**; tweet ID at `resp.json()["data"]["id"]`. ```python resp = oauth.post("https://api.x.com/2/tweets", json={"text": "Hello"}) tweet_id = resp.json()["data"]["id"] ``` Reply pa