Skip to content
cccskills
FreePublished on GitHub

x-api

X/Twitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.

The English summary is being prepared. Showing the original description.

Works withX (Twitter)
See how to install

Files included (1)

  • SKILL.md5.4 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

X API

Programmatic interaction with X (Twitter) for posting, reading, searching, and analytics.

When to Activate

  • User wants to post tweets or threads programmatically
  • Reading timeline, mentions, or user data from X
  • Searching X for content, trends, or conversations
  • Building X integrations or bots
  • Analytics and engagement tracking
  • User says "post to X", "tweet", "X API", or "Twitter API"

Authentication

OAuth 2.0 Bearer Token (App-Only)

Best for: read-heavy operations, search, public data.

# Environment setup
export X_BEARER_TOKEN="your-bearer-token"
import os
import requests

bearer = os.environ["X_BEARER_TOKEN"]
headers = {"Authorization": f"Bearer {bearer}"}

# Search recent tweets
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)

Required for: posting tweets, managing account, DMs.

# Environment setup — source before use
export X_API_KEY="your-api-key"
export X_API_SECRET="your-api-secret"
export X_ACCESS_TOKEN="your-access-token"
export X_ACCESS_SECRET="your-access-secret"
import os
from requests_oauthlib import OAuth1Session

oauth = OAuth1Session(
    os.environ["X_API_KEY"],
    client_secret=os.environ["X_API_SECRET"],
    resource_owner_key=os.environ["X_ACCESS_TOKEN"],
    resource_owner_secret=os.environ["X_ACCESS_SECRET"],
)

Core Operations

Post a Tweet

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"]

Post a Thread

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)
        resp.raise_for_status()
        tweet_id = resp.json()["data"]["id"]
        ids.append(tweet_id)
        reply_to = tweet_id
    return ids

Read User Timeline

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",
    }
)

Search Tweets

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",
    }
)

Get User by Username

resp = requests.get(
    "https://api.x.com/2/users/by/username/affaanmustafa",
    headers=headers,
    params={"user.fields": "public_metrics,description,created_at"}
)

Upload Media and Post

# Media upload uses v1.1 endpoint

# Step 1: Upload media
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"]

# Step 2: Post with media
resp = oauth.post(
    "https://api.x.com/2/tweets",
    json={"text": "Check this out", "media": {"media_ids": [media_id]}}
)

Rate Limits

X API rate limits vary by endpoint, auth method, and account tier, and they change over time. Always:

  • Check the current X developer docs before hardcoding assumptions
  • Read x-rate-limit-remaining and x-rate-limit-reset headers at runtime
  • Back off automatically instead of relying on static tables in code
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")

Error Handling

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

  • Never hardcode tokens. Use environment variables or .env files.
  • Never commit .env files. Add to .gitignore.
  • Rotate tokens if exposed. Regenerate at developer.x.com.
  • Use read-only tokens when write access is not needed.
  • Store OAuth secrets securely — not in source code or logs.

Integration with Content Engine

Use content-engine skill to generate platform-native content, then post via X API:

  1. Generate content with content-engine (X platform format)
  2. Validate length (280 chars for single tweet)
  3. Post via X API using patterns above
  4. Track engagement via public_metrics

Related Skills

  • content-engine — Generate platform-native content for X
  • crosspost — Distribute content across X, LinkedIn, and other platforms

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates.

The English summary is being prepared. Showing the original description.

sayasaya8039/ZWG_Terminal2Updated Jun 8, 2026

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing.

The English summary is being prepared. Showing the original description.

sayasaya8039/ZWG_Terminal2Updated Jun 8, 2026

Engineering operating model for teams where AI agents generate a large share of implementation output.

The English summary is being prepared. Showing the original description.

sayasaya8039/ZWG_Terminal2Updated Jun 8, 2026

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns.

The English summary is being prepared. Showing the original description.

sayasaya8039/ZWG_Terminal2Updated Jun 8, 2026

REST API design patterns including resource naming, status codes, pagination, filtering, error responses, versioning, and rate limiting for production APIs.

The English summary is being prepared. Showing the original description.

sayasaya8039/ZWG_Terminal2Updated Jun 8, 2026

Write articles, guides, blog posts, tutorials, newsletter issues, and other long-form content in a distinctive voice derived from supplied examples or brand guidance. Use when the user wants polished written content longer than a paragraph, especially when voice consistency, structure, and credibility matter.

The English summary is being prepared. Showing the original description.

sayasaya8039/ZWG_Terminal2Updated Jun 8, 2026

See all skills by sayasaya8039

Report a problem with this skill