x-api
Scannednpx machina-cli add skill rockyco/claude-x-plugin/x-api --openclawX API Knowledge
Post Creation
X API v2 endpoint for creating posts:
POST https://api.x.com/2/tweets
Authorization: Bearer {access_token}
Content-Type: application/json
{"text": "Hello world"}
With media:
{
"text": "Check this out",
"media": {
"media_ids": ["1234567890"]
}
}
Authentication
X uses OAuth 2.0 with PKCE (Proof Key for Code Exchange):
- Authorization URL:
https://x.com/i/oauth2/authorize - Token URL:
https://api.x.com/2/oauth2/token - Access tokens expire in 2 hours
- Refresh tokens valid for 6 months (requires
offline.accessscope) - The plugin auto-refreshes tokens before each API call
Required scopes: tweet.read tweet.write users.read media.write offline.access
Media Upload
Single-shot upload to POST https://api.x.com/2/media/upload:
- Format:
multipart/form-data - Fields:
media_data(base64),media_category("tweet_image") - Returns
data.id(media ID string)
Constraints
- Max 4 images per post
- Images: max 5 MB (JPG, PNG, GIF, WEBP)
- GIFs: max 15 MB, resolution max 1280x1080
- Videos: max 512 MB, 0.5-140 seconds (requires chunked upload)
Post Content Guidelines
- Free tier: 280 characters per post
- Premium/X Blue: 25,000 characters
- Hashtags: use sparingly, 2-3 max
- @mentions count toward character limit
- URLs are shortened to 23 characters by t.co
- Line breaks are preserved
Free Tier Limits
- 1,500 posts per month
- Write-only (cannot read timelines)
- Media upload available with
media.writescope - Rate limit: measured in 24-hour windows
Common Errors
- 401 Unauthorized: Token expired. The plugin auto-refreshes, but if refresh fails, re-run
/x:setup. - 403 Forbidden: Missing required scope or app permissions. Check User Authentication Settings in the developer portal.
- 429 Too Many Requests: Rate limited. Wait and retry.
- 400 Bad Request: Invalid payload. Check character count and media IDs.
Reply and Quote Posts
Reply:
{
"text": "Great point!",
"reply": {"in_reply_to_tweet_id": "1234567890"}
}
Quote:
{
"text": "This is interesting",
"quote_tweet_id": "1234567890"
}
Scripts Location
The X API scripts are at ${CLAUDE_PLUGIN_ROOT}/scripts/:
oauth-server.py- OAuth 2.0 PKCE flow with local callback server and auto token refreshx-api.py- Post creation, media upload, auth check, token refresh
Source
git clone https://github.com/rockyco/claude-x-plugin/blob/main/skills/x-api/SKILL.mdView on GitHub Overview
This skill covers creating posts with X API v2, uploading media, and handling authentication. It includes post formatting best practices, content guidelines, and common error scenarios to help you troubleshoot and stay within limits.
How This Skill Works
Integrate with X API v2 by calling POST /2/tweets with a JSON payload such as {"text": "Hello world"}. For media, upload with /2/media/upload to obtain media_ids and attach them to tweets. The plugin uses OAuth 2.0 PKCE, auto-refreshes tokens before API calls, and scripts live at ${CLAUDE_PLUGIN_ROOT}/scripts/ (oauth-server.py and x-api.py).
When to Use It
- When composing new posts via API using the X API v2 endpoint
- When attaching media to tweets and handling media IDs
- During OAuth 2.0 PKCE authentication and token refresh
- When validating content length, hashtags, and URLs under guidelines
- When debugging common errors (401, 403, 429, 400) and resolving them
Quick Start
- Step 1: Obtain OAuth 2.0 PKCE tokens via the provided OAuth flow (https://x.com/i/oauth2/authorize and the token endpoint).
- Step 2: Create a post using POST https://api.x.com/2/tweets with {"text": "Your message"}.
- Step 3: If using media, upload media via /media/upload to get media_ids and include them in the tweet payload.
Best Practices
- Keep posts within the free tier character limit (280) unless a premium tier is active
- Limit hashtags to 2-3 per post to avoid clutter and potential suppression
- Upload media via /media/upload first to obtain media_ids and include them in the tweet payload
- Be mindful of URL shortening (t.co) and its 23-character impact on total length
- Auto-refresh tokens before each API call to minimize authentication errors
Example Use Cases
- POST https://api.x.com/2/tweets with {"text":"Hello world"}
- POST with media: {"text":"Check this out","media":{"media_ids":["1234567890"]}}
- Reply: {"text":"Great point!","reply":{"in_reply_to_tweet_id":"1234567890"}}
- Quote: {"text":"This is interesting","quote_tweet_id":"1234567890"}
- OAuth PKCE flow with token refresh using oauth-server.py in CLAUDE_PLUGIN_ROOT/scripts/