---
name: "Twitter/X API"
description: "Skill for Twitter/X API — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "social"
agents: ["claude-code", "codex", "gemini"]
tags: ["twitter-api", "social", "auto-generated"]
---

# Twitter/X API

---
name: Twitter/X API
description: Use when working with the X (formerly Twitter) API for posting tweets, managing accounts, retrieving user data, searching content, or building social media applications
metadata:
  author: skynet
  version: 1.0.0
category: social
---

# Twitter/X API Skill

## Prerequisites
- X Developer Account with API keys
- Bearer Token or OAuth 1.0a/2.0 credentials
- API access tier (Free, Basic, Pro, or Enterprise)

## Authentication Setup

### Environment Variables
```bash
export TWITTER_BEARER_TOKEN="your_bearer_token"
export TWITTER_API_KEY="your_api_key"
export TWITTER_API_SECRET="your_api_secret"
export TWITTER_ACCESS_TOKEN="your_access_token"
export TWITTER_ACCESS_TOKEN_SECRET="your_access_token_secret"
```

### Test Authentication
```bash
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/users/me"
```

## Common Operations

### Post a Tweet
```bash
# Simple text tweet
curl -X POST "https://api.twitter.com/2/tweets" \
     -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"text":"Hello from the API!"}'

# Tweet with media
curl -X POST "https://api.twitter.com/2/tweets" \
     -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"text":"Check out this image!", "media":{"media_ids":["media_id_here"]}}'
```

### Search Tweets
```bash
# Basic search
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/tweets/search/recent?query=python&max_results=10"

# Advanced search with filters
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/tweets/search/recent?query=python%20-is:retweet&tweet.fields=public_metrics,created_at&max_results=50"
```

### Get User Information
```bash
# Get user by username
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/users/by/username/elonmusk?user.fields=public_metrics,verified"

# Get multiple users
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/users?ids=12,13&user.fields=created_at,description"
```

### Get User's Tweets
```bash
# Get recent tweets from user
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/users/12/tweets?max_results=20&tweet.fields=created_at,public_metrics"

# Exclude retweets and replies
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/users/12/tweets?exclude=retweets,replies&max_results=10"
```

## Python Implementation

### Basic Setup
```python
import requests
import os

class TwitterAPI:
    def __init__(self):
        self.bearer_token = os.getenv('TWITTER_BEARER_TOKEN')
        self.headers = {'Authorization': f'Bearer {self.bearer_token}'}
    
    def search_tweets(self, query, max_results=10):
        url = f"https://api.twitter.com/2/tweets/search/recent"
        params = {
            'query': query,
            'max_results': max_results,
            'tweet.fields': 'created_at,public_metrics'
        }
        response = requests.get(url, headers=self.headers, params=params)
        return response.json()
    
    def post_tweet(self, text):
        url = "https://api.twitter.com/2/tweets"
        payload = {'text': text}
        response = requests.post(url, headers=self.headers, json=payload)
        return response.json()
```

### Batch Operations
```python
def get_multiple_users(usernames):
    api = TwitterAPI()
    url = "https://api.twitter.com/2/users/by"
    params = {
        'usernames': ','.join(usernames),
        'user.fields': 'public_metrics,verified,created_at'
    }
    response = requests.get(url, headers=api.headers, params=params)
    return response.json()

# Usage
users = get_multiple_users(['elonmusk', 'sundarpichai', 'satyanadella'])
```

## Decision Trees

### Rate Limit Strategy
```
Rate limit hit (429)?
├── Essential request?
│   ├── Yes → Wait for reset window
│   └── No → Queue for later
└── Implement exponential backoff
    ├── Start with 1 minute
    ├── Double each retry
    └── Max 15 minutes
```

### API Tier Selection
```
What's your use case?
├── Learning/Testing → Free Tier (1,500 tweets/month)
├── Small App → Basic Tier ($100/month)
├── Analytics → Pro Tier ($5,000/month)
└── Enterprise → Custom pricing
```

### Tweet Posting Strategy
```
Tweet content ready?
├── Text only → Use /tweets endpoint
├── Has media?
│   ├── Upload media first → /media/upload
│   └── Then tweet with media_ids
└── Thread?
    ├── Post first tweet
    └── Reply to previous tweet ID
```

## Advanced Workflows

### Upload and Tweet Image
```bash
# 1. Upload media
MEDIA_ID=$(curl -X POST "https://upload.twitter.com/1.1/media/upload.json" \
  -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
  -F "media=@image.jpg" | jq -r '.media_id_string')

# 2. Tweet with media
curl -X POST "https://api.twitter.com/2/tweets" \
     -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     -H "Content-Type: application/json" \
     -d "{\"text\":\"Check this out!\", \"media\":{\"media_ids\":[\"$MEDIA_ID\"]}}"
```

### Create Tweet Thread
```python
def create_thread(tweets):
    api = TwitterAPI()
    thread_id = None
    
    for tweet_text in tweets:
        payload = {'text': tweet_text}
        if thread_id:
            payload['reply'] = {'in_reply_to_tweet_id': thread_id}
        
        response = api.post_tweet(payload)
        thread_id = response['data']['id']
        time.sleep(1)  # Rate limit prevention
    
    return thread_id
```

### Monitor Mentions
```python
def monitor_mentions(user_id):
    url = f"https://api.twitter.com/2/users/{user_id}/mentions"
    params = {
        'tweet.fields': 'created_at,author_id',
        'max_results': 100
    }
    
    while True:
        response = requests.get(url, headers=headers, params=params)
        mentions = response.json()
        
        for mention in mentions.get('data', []):
            process_mention(mention)
        
        time.sleep(60)  # Check every minute
```

## Error Handling

### Common HTTP Status Codes
- `400` - Bad Request: Invalid parameters
- `401` - Unauthorized: Invalid credentials
- `403` - Forbidden: Insufficient permissions
- `404` - Not Found: User/tweet doesn't exist
- `429` - Too Many Requests: Rate limit exceeded

### Rate Limit Headers
```python
def check_rate_limits(response):
    remaining = response.headers.get('x-rate-limit-remaining')
    reset_time = response.headers.get('x-rate-limit-reset')
    
    if remaining and int(remaining) < 5:
        reset_timestamp = int(reset_time)
        wait_time = reset_timestamp - time.time()
        print(f"Rate limit low. Reset in {wait_time} seconds")
```

## Troubleshooting

### "Invalid or expired token"
```bash
# Verify token format
echo $TWITTER_BEARER_TOKEN | wc -c  # Should be ~113 characters

# Test with fresh token
curl -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/users/me"
```

### "Forbidden" Error (403)
- Check API access level in developer portal
- Verify app permissions (Read/Write)
- Ensure endpoint is available in your tier

### "Duplicate content" Error
```python
# Add timestamp to avoid duplicates
import time
text = f"My tweet content {int(time.time())}"
```

### Rate Limit Exceeded
```python
def handle_rate_limit(response):
    if response.status_code == 429:
        reset_time = int(response.headers.get('x-rate-limit-reset', 0))
        wait_seconds = max(reset_time - time.time(), 0) + 1
        print(f"Rate limited. Waiting {wait_seconds} seconds...")
        time.sleep(wait_seconds)
        return True
    return False
```

### JSON Decode Error
```bash
# Check response content type
curl -I -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" \
     "https://api.twitter.com/2/tweets/search/recent?query=test"

# Validate JSON response
curl -s "https://api.twitter.com/2/users/me" \
     -H "Authorization: Bearer $TWITTER_BEARER_TOKEN" | jq .
```
