Twitter/X API — SKILL.md
Raw skill file that agents receive when using this skill
---
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 .
```
curl -s https://skills.skynet.ceo/api/skills/twitter-api/skill.md